Hibernate: why do we use inverse=”true” in many to many

I was going through the hibernate tutorial, I couldn’t understand why they used inverse=”true” in the examples. The tutorial wasn’t clear enough.

Consider the case given in the example: Event and Person are two entities and there is a many to many mapping between  them. So when you add a event to a person using this code:

Event e=(Event)session.load(Event.class,eid);
Person p=(Person)session.load(Person.class,pid);
p.getEvents().add(e);
return p;//End of method

As in the above code, if you are making changes to only one end of the relationship (the Person end) then you don’t have to set inverse=”true” in the hbm file. But if you want the addtion of Events to a Person reflect on the Events entity (so that you can get persons attending an event using e.getPersons() )  with out causing hibernate to query the database when you do a event.getPersons(), you can do some thing like this

p.getEvents().add(e);//line a
e.getPersons().add(p);//line b
return p;//End of method

In this case, if you don’t set an inverse=”true”, you will get an error when hibernate tries to insert twice in the join table PERSON_EVENTS, once for line a and once for line b. Setting inverse=”true” on one side of the relationship tells hibernate to ignore changes to the relationship for this ‘many to many’ property. So if you set set inverse to true on one end of the relationship, you’ll see only one insert statement in hibernate log. If you set it on both ends, then hibernate won’t even insert a record in thte join table. If you still didn’t understand, please post your question and I’ll try to answer it.

Advertisements

10 Responses to Hibernate: why do we use inverse=”true” in many to many

  1. Murugesan says:

    Still I am not clear. I am beginner of Hibernate. Can you explain me with some details

  2. mahesh says:

    hi suneel can u provide the same example with graphical rep..(a pic is worth 1000 words ..u see)

  3. mahesh says:

    suneel cud u also provide the class and their hbm files ….
    one thing i’m unable to figure out is where should i put inverse=”true” in hbm…

    clarify me on this

    mahesh

  4. Niranjan Kumar says:

    Very Clearly explained…. Thanks

  5. Pradeep says:

    A indeed good explanation for many to many relationship. But what if the relationship is one to many where the one end has a set or a list. I have read that when it is a list/Map the value of inverse will be false at the list/Map end whereas in case of a set the many end will be inverse=”true”. Kindly explain.

  6. Jaider says:

    This depend on which hbm’ file you put the TAG, inverse=”true”,

    If I add many events to a Person… and
    Many people(Persons) to a Event…
    And save both.
    Then if the TAG is in Person.hbm.xml… only it creates many-to-many relation defined in Event. or viceversa.

    Of course if I dont use this Tag, it try to insert the relations in both way, but if there are repeated, then throws an exeption 😦

    How can solve this problem??????

  7. Anil says:

    Hi …
    I did understand inverse = “true”.
    Could you please explain inverse concept in bidirectional one-to-many relationship?

  8. If we don’t put inverse=true in any side of many-to-many relation then two insert statements are being executed. But in case of one-to-many extra update statement is executed for foreign key. Then why this difference? Or what is exactly inverse does ?

  9. Q.Again I forgot to mention that if we put inverse=true both side , cascade = all then no insert statement is executing in junction table..

    code:-

    DOCTOR_SEQ

    MEDICALSHOP_SEQ

    SessionFactory factory = new Configuration().configure().buildSessionFactory();

    Session session = factory.openSession();

    Transaction tx = session.beginTransaction();

    DoctorRef d = new DoctorRef();
    d.setFirstName(“First Name”);
    d.setLastName(“Last Name”);
    d.setRegno(“REGNO”);
    d.setSex(“M”);
    d.setExperience(2);

    DoctorRef d1 = (DoctorRef)session.load(DoctorRef.class, new Long(132));

    MedicalShop m = new MedicalShop();
    m.setName(“Shop name1”);
    m.setRegistraionno(“SHOP REG”);
    m.setStatus(“A”);

    d1.getMedicalShopSet().add(m);
    m.getDoctorSet().add(d1);

    //m.get

    session.save(d1);

    tx.commit();

    It generates:-
    Hibernate: select doctorref0_.id as id5_0_, doctorref0_.version as version5_0_, doctorref0_.firstName as firstName5_0_, doctorref0_.lastName as lastName5_0_, doctorref0_.experience as experience5_0_, doctorref0_.regno as regno5_0_, doctorref0_.sex as sex5_0_ from doctor doctorref0_ where doctorref0_.id=?
    Hibernate: select medicalsho0_.doctorid as doctorid1_, medicalsho0_.medicalshopid as medicals2_1_, medicalsho1_.ID as ID7_0_, medicalsho1_.NAME as NAME7_0_, medicalsho1_.STATUS as STATUS7_0_, medicalsho1_.REGISTRAIONNO as REGISTRA4_7_0_, medicalsho1_.LOCATIONID as LOCATIONID7_0_ from DOCTORMEDICALSHOPMAP medicalsho0_, MEDICALSHOP medicalsho1_ where medicalsho0_.medicalshopid=medicalsho1_.ID(+) and medicalsho0_.doctorid=?
    Hibernate: select MEDICALSHOP_SEQ.nextval from dual
    Hibernate: insert into MEDICALSHOP (NAME, STATUS, REGISTRAIONNO, LOCATIONID, ID) values (?, ?, ?, ?, ?)
    Hibernate: update doctor set version=?, firstName=?, lastName=?, experience=?, regno=?, sex=? where id=? and version=?
    Hibernate: insert into DOCTORMEDICALSHOPMAP (doctorid, medicalshopid) values (?, ?)

    Q. Here why update statement is executing?

    All are to understand what inverse exactly does??

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: