Two Laptop Bag
The moose likes Object Relational Mapping and the fly likes Newbie JPA question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Newbie JPA question" Watch "Newbie JPA question" New topic

Newbie JPA question

Sam Mc Kee

Joined: Aug 20, 2010
Posts: 3
I'm trying to understand what exactly gets persisted automagically in a one-to-many relationship. I have a timecard object that owns a collection of timecard day objects and intend for simplicity's sake that this be a one-way relationship, i.e. you get the timecard days from the timecard object and not the other way around. So in my Timecard class I have this:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "timecard_id")
private List<TimecardDay> days;

and in my TimecardDay object I have no relationship mapped. The timecard_id column is the PK of the timecard table and has a foreign key mapping from a timecard_id column in the timecard_days table.

After I create my Timecard tc object, must I em.persist(tc) first, then add all the timecard days to it and persist again?

When I tried just adding all the timecard days to the timecard object and then calling em.persist(tc) it gave me an error message saying it had a foreign key conflict on the statement "INSERT INTO MOPS_Timecard_Day (timecard_id, work_type_id, day) VALUES (?, ?, ?) bind => [0, 2, 5]", which suggests to me that there is no mechanism to set the parent ID on the child object unless I first persist the parent object, flush, read the parent id and set it on the child objects myself. Is this correct? Or is there a way to do the whole thing in a single persist call?

Sorry for the newbie question, but I've Googled this to death, and it's not at all clear to me why there's a @OneToMany annotation at all if I have to do it in two steps.


James Sutherland
Ranch Hand

Joined: Oct 01, 2007
Posts: 553
In general it is best to define a OneToMany using a bidirectional relationship (ManyToOne back), this way the target object has access to the foreign key.

Defining the @JoinColumn in the source mean the source will write the foreign key, and the target should not map it. If you do map it in the target you must make it read-only (insertable/updateable=false), and it will be incorrect until you refresh it after insert.

You can also use a @JoinTable for a OneToMany if you want it to be unidirectional, which is better than using a @JoinColumn in the source (which is why it is the default).


TopLink : EclipseLink : Book:Java Persistence : Blog:Java Persistence Performance
Witold Marshal
Ranch Hand

Joined: Feb 05, 2012
Posts: 48
Insted calling persist second time (which will obviously cause an Exception) call merge on that instace after setting new object into relation list. Merge after cascading will create new records from instances stored in the list.
I agree. Here's the link:
subject: Newbie JPA question
jQuery in Action, 3rd edition