-->
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.  [ 11 posts ] 
Author Message
 Post subject: many-to-many association table persistence problem
PostPosted: Thu Sep 02, 2004 2:49 pm 
Newbie

Joined: Tue Aug 03, 2004 1:43 pm
Posts: 7
Location: Chapel Hill, NC
Anyone know why the many-to-many mappings below won't persist data into the association table (a2b)? All of the data gets persisted except the associtations, which is unfortunate since that's what I am most interested in. Nothing unusual in the logs and show_sql shows a query to 'a2b' but not an insert of any data.

Hibernate version:2.1.6

Mapping documents:

Alpha.hbm.xml
Code:
<hibernate-mapping package="com.rhoworld.tests.sharedcollection">
   <class name="Alpha" table="alpha">
      <id name="id" column="id" type="java.lang.Integer">
         <generator class="native"/>
      </id>
      <set name="betas" inverse="false" table="a2b" lazy="true" cascade="all-delete-orphan">
               <key column="alpha_id"/>
               <many-to-many column="beta_id" class="Beta"/>
        </set>      
   </class>
</hibernate-mapping>

Beta.hbm.xml
Code:
<hibernate-mapping package="com.rhoworld.tests.sharedcollection">
   <class name="Beta" table="beta">
      <id name="id" column="id" type="java.lang.Integer">
         <generator class="native"/>
      </id>
      <set name="alphas" inverse="true" table="a2b" lazy="true">
               <key column="beta_id"/>
               <many-to-many column="alpha_id" class="Alpha"/>
        </set>
   </class>

</hibernate-mapping>

Code between sessionFactory.openSession() and session.close():
Code:
      Configuration config=new Configuration();
      config.addClass(Alpha.class);
      config.addClass(Beta.class);
      SessionFactory factory=config.buildSessionFactory();
      Session session=factory.openSession();
      Alpha a1=new Alpha();
      Alpha a2=new Alpha();
      Beta b1=new Beta();
      Beta b2=new Beta();
      Beta b3=new Beta();
      session.saveOrUpdate(b1);
      session.saveOrUpdate(b2);
      session.saveOrUpdate(b3);
      session.saveOrUpdate(a1);
      session.saveOrUpdate(a2);
      Integer a1key=a1.getId();
      Integer a2key=a2.getId();
      Integer b1key=b1.getId();
      Integer b2key=b2.getId();
      Integer b3key=b3.getId();
      a1=null;
      a2=null;
      b1=null;
      b2=null;
      b3=null;
      System.gc();
      session.disconnect();
      session=factory.openSession();
      a1=(Alpha)session.load(Alpha.class, a1key);
      a2=(Alpha)session.load(Alpha.class, a2key);      
      b1=(Beta)session.load(Beta.class, b1key);
      b2=(Beta)session.load(Beta.class, b2key);
      b3=(Beta)session.load(Beta.class, b3key);
      a1.addBeta(b1);
      a1.addBeta(b2);
      a1.addBeta(b3);
      b1.addAlpha(a1);
      b2.addAlpha(a1);
      b3.addAlpha(a1);
      assertTrue(b1.getAlphas().contains(a1)); //Pass
      assertTrue(b2.getAlphas().contains(a1)); //Pass
      assertTrue(b3.getAlphas().contains(a1)); //Pass
      assertTrue(a1.getBetas().contains(b1)); //Pass
      assertTrue(a1.getBetas().contains(b2)); //Pass
      assertTrue(a1.getBetas().contains(b3)); //Pass
      assertTrue(a2.getBetas().isEmpty()); //Pass
      a1key=a1.getId();
      a2key=a2.getId();
      b1key=b1.getId();
      b2key=b2.getId();
      b3key=b3.getId();
      a1=null;
      a2=null;
      b1=null;
      b2=null;
      b3=null;
      System.gc();
      session.disconnect();
      session=factory.openSession();
      a1=(Alpha)session.load(Alpha.class, a1key);
      a2=(Alpha)session.load(Alpha.class, a2key);      
      b1=(Beta)session.load(Beta.class, b1key);
      b2=(Beta)session.load(Beta.class, b2key);
      b3=(Beta)session.load(Beta.class, b3key);
      assertTrue(!b1.getAlphas().isEmpty());  //Fail.
      assertTrue(!b2.getAlphas().isEmpty());  //Fail.
      assertTrue(!b3.getAlphas().isEmpty());  //Fail.
      assertTrue(!a1.getBetas().isEmpty());   //Fail.
      assertTrue(a2.getBetas().isEmpty());    //Fail.
      assertTrue(b1.getAlphas().contains(a1)); //Fail.
      assertTrue(b2.getAlphas().contains(a1)); //Fail.
      assertTrue(b3.getAlphas().contains(a1)); //Fail.
      assertTrue(a1.getBetas().contains(b1)); //Fail.
      assertTrue(a1.getBetas().contains(b2)); //Fail.
      assertTrue(a1.getBetas().contains(b3)); //Fail.


Name and version of the database you are using: HSQL (Unknown Version. Assuming latest.)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 02, 2004 3:36 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
stacktrace?

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 02, 2004 3:56 pm 
Newbie

Joined: Tue Aug 03, 2004 1:43 pm
Posts: 7
Location: Chapel Hill, NC
No stacktrace. It just doesn't work.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 02, 2004 4:08 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
i just don't see any begin or commit in your code

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 03, 2004 8:51 am 
Newbie

Joined: Tue Aug 03, 2004 1:43 pm
Posts: 7
Location: Chapel Hill, NC
If you're referring to creating and commiting a Transaction, I believe you don't have to do as such to save data and have it map correctly. Unless there something needlessly sneaky doing on in the internals....?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 03, 2004 8:57 am 
Newbie

Joined: Tue Aug 03, 2004 1:43 pm
Posts: 7
Location: Chapel Hill, NC
Alright, I added a Transaction around each save and it works now. This is rather perplexing to me, since it seems that many-to-many association mappings aren't getting saved unless they're inside a Transaction, even if the objects which are being mapped are already in Hibernate. (I can understand if they weren't being mapped because they weren't previously saved)[/i]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 03, 2004 9:04 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
i'm not sure i understand what you're saying... so forgive me if my answer seems strange.

It's known that you must manage the transaction, hibernate doesn't do it for you.

In your case, you should only have 1 beginTrans (at the beginning) and one commit(at the end) + rollback if you catch exceptions.

I advice to use session.flush() to debug.

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Last edited by anthony on Fri Sep 03, 2004 9:06 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 03, 2004 9:05 am 
Newbie

Joined: Tue Aug 03, 2004 1:43 pm
Posts: 7
Location: Chapel Hill, NC
But you're not required to use Transactions, correct?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 03, 2004 9:08 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
see my previsou post, you must at least manage one transaction for a unit of business code (generally one http request).
Of course you don't need to use one transaction per save (or update).

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 03, 2004 9:22 am 
Newbie

Joined: Tue Aug 03, 2004 1:43 pm
Posts: 7
Location: Chapel Hill, NC
Is this requirement documented somewhere? The code examples from the Hibernate Manual in section 9.4 do not specify that Transactions are required, and even provide examples without them (although none of them may have any mappings).

I'm not saying this is a bug, but it seems like very unfriendly behaviour, to persist a parent object and not its mapped children just because the operation is not done in a transaction. Moreso, considering that Hibernate doesn't treat this as an error or raise a warning.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 03, 2004 10:25 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Your hitting a database. Seems common sense that transactions would be needed.

If you are using JTA to manage the transactions for you, then no you don't need to explicitly manage transactions. But otherwise yes.


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