15

I have fairly typical scenario where there is a main @Entity and everything inside him is embeddable (so everything inside doesn't make sense without the parent). Now JPA 2.0 is blocking me to nest a @ElementCollection inside a @Embeddable defined in another @ElementCollection:

JSR-317 2.6 Collections of Embeddable Classes and Basic Types An embeddable class (including an embeddable class within another embeddable class) that is contained within an element collection must not contain an element collection, nor may it contain a relationship to an entity other than a many-to-one or one-to-one relationship

Now the question is: why is this? A simple example:

@Entity
public class Tournament {
    @Id
    Long id;

    @ElementCollection
    @CollectionTable
    private List<Edition>;
}

@Embeddable
public class Edition {

    @ElementCollection
    @CollectionTable
    private List<Round>
}

@Embeddable
public class Round {

    blabla;
}

What's the problem having this? This is just an example, you could define Round and Edition as Entity and solve the problem, but in my case for a number of reasons I need to enforce that something very nested doesn't make sense without his parent.

Why JPA 2.0 has to stop me doing this?

Francesco
  • 857
  • 1
  • 11
  • 26

1 Answers1

21

Your situation violates the specification element you pasted in:

Edition is itself @Embeddable, and contains an element collection of Round, and thus:

An embeddable class (Edition) that is contained within an element collection (Tournament.editions) must not contain an element collection (Edition.rounds).

As to why you can't do this - if you look at the examples from http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection then you'll see that the child (Edition) would be mapped with only a FK back to the owner (Tournament.id) without an ID column of its own - on the grounds that as a Weak entity, it has no ID of its own, and is only defined by reference to the ID of the Tournament.

Taking the Round, if that too is a weak entity, then it should be defined by FK reference to the Edition - but we already said that has no ID of its own, so you can't map this in the DB without adding an ID to the Edition - at which point it would be an entity in its own right, and not be simply @Embeddable.

Looking at the Wikipedia example from the comment below - http://en.wikipedia.org/wiki/Weak_entity - the examples of weak entities there are OrderNumber, CustomerNumber etc - things which only ever make any sense when embedded in another object.

You can still have entities which have parent mappings (i.e. a Tournament reference on the Edition) and/or bi-directional references. You can force the parent to be defined on the Edition with a nullable=false attribute on the @ManyToOne annotation, and thus enforce the requirements of your model.

stevestorey
  • 448
  • 3
  • 7
  • As I wrote in the question, it is needed by the model: it shouldn't be possible to load an Edition without his Tournament, and an Edition cannot exists if you don't have a Tournament first. It's the notion of [Weak Entity](http://en.wikipedia.org/wiki/Weak_entity) that is well known in ER diagrams but seems to be not well implemented in JPA. I was just trying to understand why in JPA you cannot have more nested embeddable elementcollections (maybe there is an implementation problem?), that is a common way of describing things in the real world. – Francesco Mar 02 '14 at 11:44
  • 1
    Thanks for your detailed answer. At the end I realised Embeddable does not map exactly with the idea of weak entity. A weak entity should have a composite primary key composed by the foreign key to the parent entity + his own id, and this is not the case for a Embeddable object. So I think the last option you gave is the most reasonable, even though I thought there was something more direct to map a weak entity, but I was wrong. – Francesco Mar 02 '14 at 14:17