<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Adrian Smith&#039;s Blog &#187; hibernate</title>
	<atom:link href="http://www.17od.com/tag/hibernate/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.17od.com</link>
	<description></description>
	<lastBuildDate>Sun, 20 Nov 2011 20:04:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Problem with Hibernate many-to-many association</title>
		<link>http://www.17od.com/2006/11/09/problem-with-hibernate-many-to-many-association/</link>
		<comments>http://www.17od.com/2006/11/09/problem-with-hibernate-many-to-many-association/#comments</comments>
		<pubDate>Thu, 09 Nov 2006 20:59:18 +0000</pubDate>
		<dc:creator>Adrian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.17od.com/2006/11/09/problem-with-hibernate-many-to-many-association/</guid>
		<description><![CDATA[This post is really a record for both myself and anyone else who ever comes across the same problem. The Problem: Given two entities with a many-to-many association between them, the join table isn&#8217;t being populated when an association is made. The Problem Set: Two persistent entities, &#8220;Group&#8221; and &#8220;ActivityType&#8221; with a many-to-many association between [...]]]></description>
			<content:encoded><![CDATA[<p>This post is really a record for both myself and anyone else who ever comes across the same problem.</p>
<p><strong>The Problem</strong>: Given two entities with a many-to-many association between them, the join table isn&#8217;t being populated when an association is made.</p>
<p><strong>The Problem Set</strong>: Two persistent entities, &#8220;Group&#8221; and &#8220;ActivityType&#8221; with a many-to-many association between them. A few snippets from the relevant files&#8230;</p>
<p><em>Group.hbm.xml</em></p>
<pre>
&lt;set name="activityTypes" table="group_activity_type" cascade="save-update" lazy="true"&gt;
    &lt;key column="group_id"/&gt;
    &lt;many-to-many column="activity_type_id" class="ActivityType"/&gt;
&lt;/set&gt;
</pre>
<p><em>ActivityType.hbm.xml</em></p>
<pre>
&lt;set name="groups" table="group_activity_type" inverse="true" cascade="save-update" lazy="true"&gt;
    &lt;key column="activity_type_id"/&gt;
    &lt;many-to-many column="group_id" class="Group"/&gt;
&lt;/set&gt;
</pre>
<p><em>Group.java</em></p>
<pre>
private Set activityTypes = new HashSet();

public Set getActivityTypes() {
	return activityTypes;
}

public void setActivityTypes(Set activityTypes) {
	this.activityTypes = activityTypes;
}
</pre>
<p><em>ActivityType.java</em></p>
<pre>
private Set groups = new HashSet();

public Set getGroups() {
	return groups;
}

public void setGroups(Set groups) {
	this.groups = groups;
}
</pre>
<p><em>Some test code</em></p>
<pre>
org.hibernate.classic.Session session = HibernateUtil.getSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
ManagedSessionContext.bind(session);
session.beginTransaction();

Group group = new Group();
group.setName("Test Group");
ActivityType activityType = new ActivityType();
activityType.setName("Activity Type");
activityType.getGroups().add(group);
group.getActivityTypes().add(activityType);
activityTypeDAO.saveActivityType(activityType);
groupDAO.saveGroup(group);

ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
session.getTransaction().commit();
session.close();
</pre>
<p><strong>The Solution</strong>: This took me ages to figure out but I eventually stumbled across the problem <a href="http://forum.hibernate.org/viewtopic.php?p=2328276&#038;sid=a7dc230384c6aaf1c2aa79b65f728e67">on this thread</a>. The problem is that I&#8217;m not calling session.flush() before I commit the session. Here&#8217;s the last paragraph of test code with the new flush statement.</p>
<pre>
ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
<strong>session.flush();</strong>
session.getTransaction().commit();
session.close();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.17od.com/2006/11/09/problem-with-hibernate-many-to-many-association/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Using Managed Sessions in Hibernate to Ease Unit Testing</title>
		<link>http://www.17od.com/2006/11/06/using-managed-sessions-in-hibernate-to-ease-unit-testing/</link>
		<comments>http://www.17od.com/2006/11/06/using-managed-sessions-in-hibernate-to-ease-unit-testing/#comments</comments>
		<pubDate>Mon, 06 Nov 2006 21:45:23 +0000</pubDate>
		<dc:creator>Adrian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.17od.com/2006/11/06/using-managed-sessions-in-hibernate-to-ease-unit-testing/</guid>
		<description><![CDATA[If you&#8217;ve ever tried to reuse a session in Hibernate you may have come across this exception&#8230; org.hibernate.SessionException: Session is closed! at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:49) at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1319) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301) at $Proxy0.beginTransaction(Unknown Source) .... The reason for this is that Hibernate is using &#8220;thread&#8221; managed sessions. [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever tried to reuse a session in <a title="Hibernate" href="http://www.hibernate.org/">Hibernate</a> you may have come across this exception&#8230;</p>
<pre>
org.hibernate.SessionException: Session is closed!
   at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:49)
   at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1319)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
   at $Proxy0.beginTransaction(Unknown Source)
   ....
</pre>
<p>The reason for this is that Hibernate is using &#8220;thread&#8221; managed <a title="sessions" href="http://www.hibernate.org/hib_docs/v3/reference/en/html/architecture.html#architecture-current-session">sessions</a>. With this type of session management Hibernate manages the session for you. When you first attempt to use a session Hibernate will create one and attach it to your local thread. When you commit the transaction in the session Hibernate will automatically close the session meaning it can&#8217;t be reused.</p>
<p>To get around this problem the best option is to use &#8220;managed&#8221; sessions. With managed sessions you&#8217;re in full control of creating, flushing, commiting, and closing sessions. Here&#8217;s how.</p>
<p>In your <code>hibernate.cfg.xml</code> change the property &#8220;current_session_context_class&#8221; to &#8220;managed&#8221;.</p>
<p>To create a session and start a transaction in that session do this&#8230;</p>
<pre>
   org.hibernate.classic.Session session = HibernateUtil.getSessionFactory().openSession();
   session.setFlushMode(FlushMode.MANUAL);
   ManagedSessionContext.bind(session);
   session.beginTransaction();
</pre>
<p>To commit a transaction in the session do this&#8230;</p>
<pre>
   ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
   session.flush();
   session.getTransaction().commit();
   session.close();
</pre>
<p>To use this code in unit tests I created this base unit test class that all my unit tests extend. Whenever I want to create a new session/transaction I call the method createNewSessionAndTransaction(). To commit the session&#8217;s transaction I call the method commitTransaction().</p>
<pre>
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.context.ManagedSessionContext;
import util.HibernateUtil;
import junit.framework.TestCase;

/**
 * Abstract unit test with helper methods for managed session control
 */
public abstract class ManagedSessionUnitTest extends TestCase {

   /**
    * Create a new Session.
    *
    * For this method to work, the application managed session strategy has to
    * be enabled. This basically means that the life of a session is controlled
    * by you and and not by Hibernate.
    *
    * To enable the application managed session strategy set the property
    * hibernate.current_session_context_class to "managed".
    *
    * Within this method we create a new session and set the flush mode to
    * MANUAL. This ensures that we have full control over when the session is
    * flushed to the database.
    */
   protected org.hibernate.Session createNewSession() {
      org.hibernate.classic.Session session = HibernateUtil.getSessionFactory().openSession();
      session.setFlushMode(FlushMode.MANUAL);
      ManagedSessionContext.bind(session);
      return (org.hibernate.Session) session;
   }

   /**
    * Start a new Transaction in the given session
    * @param session The session to create the transaction in
    */
   protected void startNewTransaction(Session session) {
      session.beginTransaction();
   }

   /**
    * Shortcut method that creates a new session and begins a transaction in it
    * @return A new session with a transaction started
    */
   protected org.hibernate.Session createNewSessionAndTransaction() {
      Session session = createNewSession();
      startNewTransaction(session);
      return session;
   }

   /**
    * Commit the transaction within the given session. This method unbinds
    * the session from the session context (ManagedSessionContext), flushes
    * the session, commmits the session and then closes the session
    * @param session The session with the transaction to commit
    */
   protected void commitTransaction(Session session) {
      ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
      session.flush();
      session.getTransaction().commit();
      session.close();
   }

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.17od.com/2006/11/06/using-managed-sessions-in-hibernate-to-ease-unit-testing/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

