views:

743

answers:

5

Hi,

I've got 2 entities in JPA: Entry and Comment. Entry contains two collections of Comment objects.

@Entity public class Entry { ...

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@IndexColumn(base = 1, name = "dnr")
private List<Comment> descriptionComments = new ArrayList<Comment>();

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@IndexColumn(base = 1, name = "pmnr")
private List<Comment> postMortemComments = new ArrayList<Comment>();

...

}

To store such objects, JPA+Hibernate creates "Entry" table, "Comment" table and SINGLE "Entry_Comment":

create table Entry_Comment (Entry_id integer not null, postMortemComments_id integer not null, pmnr integer not null, descriptionComments_id integer not null, dnr integer not null, primary key (Entry_id, dnr), unique (descriptionComments_id), unique (postMortemComments_id))

Storing of objects fail as descriptionComments_id and postMortemComments_id cannot be "not null" at the same time.

How do I store object containing two collections of the same type using JPA+Hibernate?

+3  A: 

To store 2 collections like that in JPA with DataNucleus (http://www.datanucleus.org) you would do exactly as you've done. You have no @JoinTable annotation hence a FK should be placed in Comment for each of the collections. If you actually do have @JoinTable somewhere (or XML equivalent) then setting the names of the respective join tables (one for each collection) would work too (so they have their own join table). Having a shared join table between 2 collections is possible in DataNucleus too, but that's not standard JPA, instead a vendor extension.

How that maps to Hibernate I've no idea, but then this is JPA so should be consistent since thats the point of having a spec ;-)

--Andy DataNucleus

DataNucleus
+1  A: 

There is a flaw with current mapping from data model/domain model point of view: you actaully have a single @OneToMany relationship between Entry and Comment. And Comment entity should have one more attribute called type that takes 2 values: 'description' or 'postMortem'.

To be inline with your current implementation of Entry entity you may want to consider breaking down Comment entity into 2 different entities (possibly using JPA inheritance features) and using @JoinTable annotation in Entry.

grigory
A: 

If all you care about is ordering, how about configuring the two index column definitions to have the same name?

Daniel Alexiuc
I tried. Hibernate still throws exception.
Vilmantas Baranauskas
+3  A: 
thyx
A: 

I'm currently adding persistance to an existing standalone java program and have run into the same problem with an entity containing two collections, both of the same type.

thyx has found a solution for Hibernate. I'm currently using Toplink and, besides, I'd prefere to adhere to the JPA spec, which doesn't have an @IndexColumn-association specified.

As a last resort I would use grigorys aproach and add an additional property to the referenced class. That would involve some refactoring of the existing code, which I would like to avoid and, frankly, which I would hope JPA would not require me to do.

If anyone has a standard JPA solution it would be greatly appreciated.