Announcement Announcement Module
No announcement yet.
Shouldn't HibernateJpaDialect.prepareTransaction call session.setDefaultReadOnly ? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Shouldn't HibernateJpaDialect.prepareTransaction call session.setDefaultReadOnly ?

    The prepareTransaction method already suppresses hibernate flushing for a read-only transaction by setting session flush mode to FlushMode.MANUAL. Shouldn't this method also call session.setDefaultReadOnly(readOnly) to tell the hibernate session to not waste resources on tracking entities that will never be flushed?

    I would insert the line
    just before
    return new SessionTransactionData(session, previousFlushMode);

    I am looking at spring 3.2.2 source.

  • #2
    No... A Transaction isn't the same as a Session... A Session can span multiple Transactions (not in parallel but serial). So IMHO it is dangerous to do so...


    • #3
      Originally posted by Marten Deinum View Post
      No... A Transaction isn't the same as a Session... A Session can span multiple Transactions (not in parallel but serial). So IMHO it is dangerous to do so...
      Yes sure - HibernateJpaDialect already supports this by using the SessionTransactionData object so it can restore the previous flush mode in cleanupTransaction method.

      My proposed code change didn't take this into account - but adding a boolean for defaultReadOnly to SessionTransactionData would make the treatment of flush mode and defaultReadOnly consistent.


      • #4
        How about the below code. This is working well for me.
              public Object prepareTransaction(EntityManager entityManager, boolean readOnly, String name)
                    throws PersistenceException {
                 Session session = getSession(entityManager);
                 FlushMode flushMode = session.getFlushMode();
                 FlushMode previousFlushMode = null;
                 boolean previousDefaultReadOnly = session.isDefaultReadOnly();// <-- changed
                 if (readOnly) {
                    // We should suppress flushing for a read-only transaction.
                    previousFlushMode = flushMode;
                 else {
                    // We need AUTO or COMMIT for a non-read-only transaction.
                    if (flushMode.lessThan(FlushMode.COMMIT)) {
                       previousFlushMode = flushMode;
                 session.setDefaultReadOnly(readOnly);// <-- changed
                 return new SessionTransactionData(session, previousFlushMode, previousDefaultReadOnly);// <-- changed
              public void cleanupTransaction(Object transactionData) {
                 ((SessionTransactionData) transactionData).reset();// <-- changed
           private static class SessionTransactionData {
              private final Session session;
              private final FlushMode previousFlushMode;
              private final boolean previousDefaultReadOnly;// <-- changed
              public SessionTransactionData(Session session, FlushMode previousFlushMode, boolean previousDefaultReadOnly) {// <-- changed
                 this.session = session;
                 this.previousFlushMode = previousFlushMode;
                 this.previousDefaultReadOnly = previousDefaultReadOnly;// <-- changed
              public void reset() {
                 if (this.previousFlushMode != null) {
                 this.session.setDefaultReadOnly(previousDefaultReadOnly);// <-- changed