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 12:57:41 -0400

Hi,
I just realized there's a mistake in the code snippet I sent. It should be:

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

Thanks,
Ellen

Ellen Kraffmiller wrote:

> 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
>>>
>>>
>>
>