1

I'm having difficulties assessing a design decision regarding entity relations in a JavaEE persistence data model.

Let's say I want to design a simple data model that's supposed to represent a chamber orchestra comprised of different types of musicians.

For now I know that there will be a flute player, a piano player, a violin player and a contrabass player, but it is expected that over the lifetime of the system, other—unforeseeable—types of musicians will be added. Therefore my supervisor told me not to use a separate entity for every type of musician, like FlutePlayer, PianoPlayer etc., but instead have a Musician entity with an attribute of enumeration type Instrument, so that new types of musicians can later be added to the system easily by adding a value to that enumeration.

On the other hand, I know for sure that every orchestra will always have exactly one piano player and exactly one contrabass player and I'd like to be able to access them conveniently. That's why I'm thinking it would be good to have a pianoPlayer and a contrabassPlayer attribute instead of just a collection of musicians in ChamberOrchestra. Think of the orchestra as a performing orchestra, so a musician cannot be part of more than one orchestra at a time.

But when implementing this, the cardinalities for the associations seem a bit odd to me because they'll establish an asymmetric relationship between ChamberOrchestra and Musician: one-to-one in one direction and many-to-one in the other direction.

I already experimented with this approach a little bit and so far it does what I expect, but the mentioned asymmetry troubles me a bit and because I'm not experienced in designing data models I'm a bit worried that such a design might have negative consequences further down the line.

So, to have a concrete question, is it okay or would it be considered bad practice to have an asymmetric relationship between entities in the sense sketched out in the code below?

@Entity
public class ChamberOrchestra {

  @OneToOne
  @JoinColumn("PIANO_PLAYER_ID")
  protected Musician pianoPlayer;

  @OneToOne
  @JoinColumn("CONTRABASS_PLAYER")
  protected Musician contrabassPlayer;

  public Musician getPianoPlayer() {
    return pianoPlayer;
  }

  public Musician getContrabassPlayer() {
    return contrabassPlayer;
  }

}

@Entity
public class Musician {

  @ManyToOne
  @JoinColumn("CHAMBER_ORCHESTRA_ID")
  protected ChamberOrchestra chamberOrchestra;

  @Column
  protected Instrument instrument;

  public ChamberOrchestra getChamberOrchestra() {
    return chamberOrchestra;
  }

  public Instrument getInstrument() {
    return instrument;
  }
}
  • 1
    But when implementing this, the cardinalities for the associations seem a bit odd to me because they'll establish an asymmetric relationship between ChamberOrchestra and Musician: one-to-one in one direction and many-to-one in the other direction. -- Are you modeling membership or participation? A musician can be a member of many orchestras, but can only participate in one at a time. – Robert Harvey Jan 12 '18 at 17:57
  • That would be participation, like in a performing orchestra. So a musician can only be part of one orchestra at a time. – anothernode Jan 13 '18 at 9:02
  • Does the piano player fetching need to be part of your relational definition? Why not just have it as a convinience method which internally loops over your musicians and pulls out the right one (or are there so many musicians that you can't load them eagerly with the orchestra) – Richard Tingle Jan 13 '18 at 10:11
  • The number of musicians per orchestra will not grow very large, so I think that would be a viable alternative. Would that be preferable in terms of a clean data model design? – anothernode Jan 13 '18 at 11:02
  • I would define "clean model design" as one where no information is duplicated. So each musician should only appear in the model once. – Robert Harvey Jan 13 '18 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.