-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Many-to-many deletes wrong relationship rows upon save
PostPosted: Wed Feb 01, 2006 9:15 pm 
Newbie

Joined: Tue Apr 19, 2005 7:36 pm
Posts: 9
Location: San Francisco, CA
Dear Hibernate Gurus!

I am migrating a code that worked with XDoclet tags (and HBM file) to annotations, and I am running into a problem with many-to-many relationship.

I have A mapped to B as a unidirectional many-to-many, with a relationiship table AB (A_id, B_id), and A being the owning (and only) side of this relationship. Save of A should cascade save of B and the relationship.

Code:
 
  a1 = new A();
  a1.addB(new B());
  a1.addB(new B());
  session.save(a1);


This correctly saves two Bs, and two rows in AB table, and row in A table (A1).

Now, I fetch A1 and reset it's ID to null (thus converting it into a 'new' instance), which is still linked to the set of Bs. What I want is to save this modified A (with null ID), linking it with the same set of B rows, without affecting relationship between A1 and B.

This works when mapped as follows using XDoclet/XML, but when mapped using annotations (see below), the relationship rows for A1 get deleted when I save (what now should be) A2. It almost looks like the sets that were fetched for A1 were "tagged" with A1, so when the same sets are found to be linked to another instance A2, hibernate decides to delete them.

Here is a summary of what happens:

Start with this:

Code:
A1 ->  A1_id, B1_id -> B1
    ->  A1_id, B2_id -> B2


Here is what I want to see after I fetch A1 and call A1.setId(null) and then save it:

Code:
A1 ->  A1_id, B1_id -> B1
    ->  A1_id, B2_id -> B2
A2 ->  A2_id, B1_id -> B1
    ->  A2_id, B2_id -> B2


Instead, with annotations, i am seeing this:

Code:
A1 
A2 ->  A2_id, B1_id -> B1
    ->  A2_id, B2_id -> B2



Here is XML mapping code that works this way:

Code:

... mapping for A ...

       <set
           name="B"
           table="AB"
           lazy="false"
           cascade="save-update"
           sort="unsorted"
           access="property" >

           <key column="A_id"/>

           <many-to-many
               class="B"
               column="B_id"
               outer-join="auto"
            />
       </set>



And here is the broken annotations mapping:

Code:
@javax.persistence.Entity(access = AccessType.FIELD)
@Table(name = "A")
@org.hibernate.annotations.Proxy(lazy = false)

class A {

    @ManyToMany(
        targetEntity = B.class,
        cascade = {},
        fetch = FetchType.EAGER)
    @JoinTable(
        table = @Table(name = "AB"),
        joinColumns = {@JoinColumn(name = "A_id")},
        inverseJoinColumns = {@JoinColumn(name = "B_id")})
    @org.hibernate.annotations.Cascade(
        {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
    private Set<B> networkPorts = new HashSet<B>();



Is there any way to prevent Hibernate from EVER deleting from my relationship table? My classes are essentially immutable, and the reason I need to do the above, is to save a new version of the object... If I could somehow tell hibernate that the many-to-many should never be deleted...

Anyone?

Thank you in advanace,
Zeel.

_________________
Thanks,
Zeel.

Software Developer, Audiologist/DJ, Cookie Monster
All Original Electronic Music - download MP3s:
=> http://www.polygroovers.com/


Top
 Profile  
 
 Post subject: Re: Many-to-many deletes wrong relationship rows upon save
PostPosted: Thu Feb 02, 2006 3:34 pm 
Newbie

Joined: Tue Apr 19, 2005 7:36 pm
Posts: 9
Location: San Francisco, CA
I think I may know what's going on.... The old XDoclet code used "property" access type on the setters for the relationship, and did this:

Code:
  public void setBs(Set bs) {
     this.bs = new HashSet(bs);
  }


What I think this did, is replace Hibernate's set with HashSet. I suspect that Hibernate's set implementation holds on to the IDs of the entity it was originally from.. Replacing the set with HashSet clears this information, and so the rows do not get deleted.

I am going to try to upgrade to beta8 so that I can override access type on a per property level and see if that helps...

_________________
Thanks,
Zeel.

Software Developer, Audiologist/DJ, Cookie Monster
All Original Electronic Music - download MP3s:
=> http://www.polygroovers.com/


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 08, 2006 1:25 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
your assumptions were rights.
The @AccessType should solve your problem

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 08, 2006 2:43 pm 
Newbie

Joined: Tue Apr 19, 2005 7:36 pm
Posts: 9
Location: San Francisco, CA
emmanuel wrote:
your assumptions were rights.
The @AccessType should solve your problem


Indeed overriding @AccessType on my collections fixed the issue.

Thanks,
Zeel.

_________________
Thanks,
Zeel.

Software Developer, Audiologist/DJ, Cookie Monster
All Original Electronic Music - download MP3s:
=> http://www.polygroovers.com/


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.