persistence@glassfish.java.net

Re: Cascade merge does not occur

From: Greg Ederer <greg_at_ergonosis.com>
Date: Mon, 08 Jan 2007 19:31:56 -0800

Hi Marina,

Thanks for the reply.

Marina Vatkina wrote:
> Hi Greg,
>
> Does the person have its relationship to the address instantiated
> at any point of time?
>
>
Yes, I add the Address instances to the Person instance via
Person.addAddress(). However, this call simply returns without doing
anything because the Addresses are already in the Person.addresses
collection.

I actually perform this call (and all of the calls on entities) using
reflection.
> Also, what is the purpose of finding the address and detaching it
> right away by closing the EM?
>
>
This is embedded within a method that gets called recursively. The call
to saveObject() takes place after the initial invocation of this method
returns. I suppose I could do all of this processing using a single EM
in object scope (or I could pass in the EM as an argument to the
recursive method). Would this solve the problem?

Thanks!

Greg

> thanks,
> -marina
>
> Greg Ederer wrote On 01/06/07 23:00,:
>
>> Hi,
>>
>> I have an entity called Person that has a list of Address entities. In
>> Person, I have:
>>
>> @OneToMany(cascade=CascadeType.ALL, mappedBy="person")
>> private List<Address> addresses = new ArrayList<Address>();
>>
>> public void addAddress(Address address)
>> {
>> if(this.getAddresses().contains(address))
>> {
>> return;
>> }
>>
>> getAddresses().add(address);
>> address.setPerson(this);
>> }
>>
>> In Address, I have:
>>
>> @ManyToOne
>> @JoinColumn(name="person", nullable = false)
>> private Person person;
>>
>> In another class, I modify a Person instance, and also modify its owned
>> Address instances, and then merge the Person instance. Afterward, the
>> changes to the Person instance are reflected in the database, as
>> expected; however, changes to the Address instances do not appear in the
>> database.
>>
>> I get a reference to each Address via EntitManager.find(), like so:
>>
>> EntityManager em = getEntityManager();
>> Object o = em.find(javaType, id);
>> em.close();
>>
>> (where javaType is a Person Class instance) rather than retrieving from
>> the Person object graph. Does this matter?
>>
>> I then merge the Person by calling the following method:
>>
>> private Object saveObject(Object o)
>> {
>> EntityManager em = getEntityManager();
>> try
>> {
>> utx.begin();
>> if(PropertyUtils.getProperty(o, "id") == null)
>> {
>> em.persist(o);
>> }
>> else
>> {
>> o = em.merge(o);
>> }
>> utx.commit();
>> }
>> catch (Exception ex)
>> {
>> //logger.severe("save failed.");
>> ex.printStackTrace();
>>
>> try
>> {
>> utx.rollback();
>> }
>> catch (Exception e)
>> {
>> //logger.severe("rollback falied.");
>> e.printStackTrace();
>> }
>> }
>> finally
>> {
>> em.close();
>> }
>>
>> return o;
>> }
>>
>> My Person instance does have an id, so em.merge(o) should get executed.
>> Also, utx is a UserTransaction obtained via @Resource.
>>
>> Can anyone tell me how to get this working?
>>
>> Thanks!
>>
>> Greg
>>
>>


-- 
| E R G O N O S I S
| Greg Ederer
| Lead Developer
| greg_at_ergonosis.com
| 360.774.6848
|