Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A good place to start is to read the well-written <a href="http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#transactions" rel="nofollow noreferrer">Hibernate documentation on transactions</a>. It is clearly stated that both <code>SessionFactory.openSession()</code> and <code>SessionFactory.getCurrentSession()</code> can be used to obtain session instances, but the do differ in the way the session is obtained.</p> <p>With <code>SessionFactory.openSession()</code> you are forcing Hibernate to open a new session for your needs, which may lead to undesired/unexpected consequences. On the contrary, if <code>SessionFactory.getCurrentSession()</code> is used a <code>Session</code> is received from a current <em>context</em>, which may mean transaction, request, etc.</p> <p>To understand it better, consider a following example: you have a service layer which needs to call methods from two DAO objects, like:</p> <pre><code>@Service public class Service { @Autowired private FirstDao firstDao; @Autowired private SecondDao secondDao; @Transactional public void serviceMethod(int param) { FirstEntity firstEntity = firstDao.getFirstEntity(param); SecondEntity secondEntity = secondDao.updateSecondEntity(firstEntity); } } </code></pre> <p>You have two options now: to have each of your DAOs implement their methods like <code>Session session = factory.openSession();</code> or <code>Session session = factory.getCurrentSession()</code>. Your belief is that both method calls (<code>firstDao.getFirstEntity</code> and <code>secondDao.updateSecondEntity</code>) should use the same session, because, at the very least your <code>firstEntity</code> is in detached state after <code>firstDao</code> method call finishes (the session should be closed there), and you should reattach it to the new session to make the code work.</p> <p>But when you call <code>getCurrentSession</code> in both DAO methods the same session instance will be returned (as it was opened beforehand by transaction management mechanism). In this case the Hibernate documentation clearly states that </p> <blockquote> <p><em>You do not need to use the Hibernate Transaction API at all with BMT or CMT, and you get automatic propagation of the "current" Session bound to the transaction.</em></p> </blockquote> <p>and all of your session management happens when you get a session instance in your DAO by calling <code>Session session = factory.getCurrentSession();</code> and that's it. Another excerpt from the Hibernate documentation:</p> <blockquote> <p>Your application code can access a "current session" to process the request by calling sessionFactory.getCurrentSession(). You will always get a <em>Session scoped to the current database transaction</em> (italics mine).</p> </blockquote> <p>Mind that <strong>Declarative transaction demarcation</strong> by Spring belobgs to the service/business layer, from which you may need to call several DAOs that use the same <code>Session</code> object, that is bound to the current transaction context. The session is opened when and transaction is started when the method marked <code>@Transactional</code> is called and transaction is committed and the session is closed when the method is executed.</p> <p>Of course that doesn't imply that session-per-transaction is the only method of implementing transaction management. There are other concepts like <em>Open session in view</em>, <em>Session-per-conversation</em>, etc. But in each case, your DAOs will get a <code>Session</code> object from the current <em>context</em> that is in turn managed by Container, or Framework, or by your written code.</p> <p>Regarding your code, I would suggest to fix the following inconsistencies:</p> <ul> <li>remove all <code>@Transactional</code> annotations from DAO layer implementations</li> <li>use only <code>sessionFactory.getCurrentSession()</code> to manipulate with the data</li> <li>go for a service layer with transaction demarcation in mind: your methods there should me marked as <code>@Transactional</code> and this way Spring will manage sessions and transactions for you (otherwise look for <em>programmatic transaction demarcation</em> in Hibernate documentation.</li> </ul> <p>Related material:</p> <ul> <li><a href="http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#transactions" rel="nofollow noreferrer">Transactions and Concurrency of Hibernate official documentation</a></li> <li><a href="https://stackoverflow.com/questions/2566618/dao-and-service-layer-in-spring-session-management">DAO and Service layer in Spring session management</a></li> <li><a href="https://stackoverflow.com/questions/8046662/hibernate-opensession-vs-getcurrentsession">Hibernate openSession() vs getCurrentSession()</a></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload