-->
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.  [ 7 posts ] 
Author Message
 Post subject: Questions about inverse=true
PostPosted: Tue Mar 28, 2006 5:01 am 
Newbie

Joined: Sun Mar 26, 2006 3:04 pm
Posts: 6
Consider the simple event and person classes from Hibernate documentation.

<class name="events.Person" table="PERSON">

<set name="events" table="PERSON_EVENT" >
<key column="PERSON_ID"/>
<many-to-many column="EVENT_ID" class="events.Event"/>
</set>

</class>

<class name="events.Event" table="EVENTS">

<set name="participants" table="PERSON_EVENT" inverse="true">
<key column="EVENT_ID"/>
<many-to-many column="PERSON_ID" class="events.Person"/>
</set>

</class>


As you can notice the inverse=true is set in the mapping of Event class. I have tried experimenting with the Person and Event class with different settings for inverse attribute (true and false).

I set inverse=false. Two test cases were adding person to an event and event into a person.
Result: In both cases an entry was created in the person_event table.


I set inverse=true. Two test cases were adding person to an event and event into a person.
Result: Adding person to an event DID NOT add a new row in the person_event table. Adding event to an person DID add a new row.

I did not see any other difference in the person/event/ or collection objects when I changed the inverse flag from true to false. Should there be any other changes?

Conclusion: Only thing inverse=true does is to direct hibernate to ignore inserts into participants collection in Events class.

Question 1: Is the conclusion correct?

Question 2: Does inverse=true lead to better performance?

Question 3: Is performance improvement the only use of inverse=true attribute?

Question 4: A developer who does not know how to “read” the hbm.xml file would make a mistake by adding person to an event and expect the system to add a new row to PERSON_EVENTS table. Is setting inverse=false the only way to get around this?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 28, 2006 9:35 am 
Newbie

Joined: Wed Sep 21, 2005 7:16 am
Posts: 10
If i remember well inverse tells Hibernate that it shouldn't maintain that side of the relationship, you'll have to do that yourself in your code.

When adding a Person to an Event you should also add the Event to the Person. You must give the Event class an addPerson method like this:

Code:
public class Event
{
    ...

    public void addPerson(Person person)
    {
       this.persons.add(person);
       person.getEvents().add(this);
    }

    // The same is true for removing a person from the relationship.
    public void removePerson(Person person)
    {
        this.persons.remove(person);       
        person.getEvents().remove(this);
    }

    ...
}


Q1: Your conclusion isn't fully correct. From Hibernate's point of view the inverse side isn't involved in a relationship. This will not only be true for inserts but for example also for deletes or for removing the relationship.
Q2: It can lead to less SQL-statements on the database so it's better for performance.
Q3: I think so.
Q4: He should always call the Event's addPerson method described above.

If anyone doesn't agree please correct me, it's been a while since i took a look at this stuff.


Top
 Profile  
 
 Post subject: removing inverse="true"
PostPosted: Thu Apr 05, 2007 10:49 am 
Newbie

Joined: Thu Mar 15, 2007 5:37 pm
Posts: 4
I was playing around with many-to-many relationship and Person-Event example. I did exactly the same what you explained above but I removed inverse="true" in both sets for Person and Event.
Thing is it tries to insert 2 identical records into PersonEvent table. I noticed that just because by mistake I created PersonEvent table without primary key. When I created a proper primary key (including Person_ID and EVENT_ID) I got "unique constraint violated" exception. Is it normal that it inserts 2 identical records in the case if I remove inverse="true" from sets definitions? It means that if I want to add Person to Event and Event to Person at the same time I should add inverse="true" at least to one of the sets otherwise it will insert 2 records to PersonEvent talbe and it will cause an exception? That sounds a bit strange...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2007 11:23 am 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
While it may seem odd, perhaps this will help:

Hibernate (by default, w/o inverse=true) will see insertions/modifications/deletions to an entity's mapped collections. To maintain the proper states, Java-wise, you would have to add an Event to the Person's events collection and add a Person to an Event's persons collection. This way, Java knows that Person x has an Event y in its collection of events and that Event y has a Person x in its collection of persons. But Hibernate thinks to itself (please excuse the anthropomorphization), "Well, there's something new in the Person x's events collection, so let's persist it! Oh, and there's something new in Event y's persons collection, so I better persist that!" When you mark one side's collection as inverse=true, it just means that Hibernate should ignore modifications to the collection, and to rely on the opposite side of the association to determine whether or not it should persist an object.

At first, it seemed odd to me as well, not being used to working with an ORM framework.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2007 9:27 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
Appear at first odd - hmmm I can see that - but the behaviour is logical.

This is just one example of the ORM miss-match problem. For this example, to create your bi-direction relationship in DB a single entry is required but in Java Objects two updates (or changes) are necessary. So you just telling the ORM that one of the two changes can be ignored by the SQL generation layer since is it not necessary to achieve the correct outcome.


Top
 Profile  
 
 Post subject: duplicate validation
PostPosted: Fri Apr 06, 2007 5:38 am 
Newbie

Joined: Thu Mar 15, 2007 5:37 pm
Posts: 4
Would it be easier for ORM framework in the case of many-to-many relationship just to check PERSONEVENT table whether it already has a record with these 2 ids rather then to introduce this flag inverse which causing so many questions here in this forum? PERSONEVENT is a part of mapping details anyway in the case of many-to-many relationship.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 07, 2007 3:47 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
Nah - I could see an argument that a many-to-many mapping could be reported as a problem/warning if there are no inverse=true entries either side (or both - which affectively makes the relationship read only - can be useful I guess).

As far as using the (correct) mapping just always update both sides. This can be done in helper methods so one call to the helper and you done.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.