persistence@glassfish.java.net

Re: Should the foreign key be set automatically when an element is added to a Collection?

From: Ellen Kraffmiller <ekraffmiller_at_hmdc.harvard.edu>
Date: Thu, 31 Aug 2006 11:58:41 -0400

Thanks, Tom.
So it seems like for every collection in my Entity object model I need
to add a special helper method to maintain the relationship,
like this:
void addStudyAuthor(StudyAuthor sa) {
    sa.setStudy(this);
    studyAuthors.add(sa);
}
Just my two cents, but I don't understand why the persistence layer
doesn't handle this. Why would you ever want to add an entity to a
Collection, and save it to the database, without setting the correct
foreign key relationship?
I also noticed then when you do the following:

Study studyA = new Study();
Study studyB = new Study();
...
sa.setStudy(studyA)
studyA.getStudyAuthors.add(sa);
em.persist(studyB);

When studyB is persisted, the fact that it has StudyAuthor sa in its
StudyAuthors collection is ignored. StudyAuthor sa still points to
studyA. It seems like the persist() call should at least throw an
Exception, because the object state you are preserving is internally
inconsistent.

I'm not sure if this is the right mailing list to ask this question, but
I'm curious about the reasoning behind this decision in the spec.
Thanks,
Ellen

Tom Ware wrote:

> Hi Ellen,
>
> The JPA specification requires that the application maintain all
> relationships.
>
> In your example, your call to sa.setStudy(study) is the correct way
> to maintain that relationship.
>
> Thanks,
> Tom
> Ellen Kraffmiller wrote:
>
>> Hi,
>> I have two Entities with a OneToMany relationship. When I deploy the
>> Entities, the correct foreign key relationship is generated in the
>> "many" side of the relationship. (Although the generated schema does
>> not define the foreign key column as required.)
>> When I add an element to the in the collection in the owning object,
>> the foreign key of the owning object is not set in the dependent
>> object. Is this the correct behavior?
>>
>> Here are the details of the two entities:
>>
>> @Entity
>> public class Study {
>> @Id
>> private Long id;
>> @OneToMany (mappedBy="study", cascade={CascadeType.REMOVE})
>> private java.util.Collection<StudyAuthor> studyAuthors;
>> ...getters and setters ...
>> }
>>
>> @Entity
>> public class StudyAuthor { @Id
>> private Long id;
>> private String value;
>> @ManyToOne
>> private Study study;
>> ...getters and setters ...
>> }
>>
>> Here is my code which adds a StudyAuthor to the collection in Study
>> (I have defined cascade-persist for the persistence unit):
>>
>> Study study = new Study();
>> StudyAuthor sa = new StudyAuthor();
>> sa.setValue(getAuthor());
>> study.setStudyAuthors(new ArrayList<StudyAuthor>());
>> study.getStudyAuthors().add(sa);
>> em.persist(study);
>>
>> The two entities are both saved in the database, but the foreign key
>> in studyAuthor is not generated unless I specifically set it
>> by adding sa.setStudy(study) before persisting. This seems like
>> something the persistence layer should be doing for me.
>>
>> Thanks,
>> Ellen
>>
>>
>