Skip to content

HibernateJpaDialect does not support setting a specific isolation level per transaction [SPR-5012] #9687

Closed
@spring-projects-issues

Description

@spring-projects-issues

Samuel Gaiffe opened SPR-5012 and commented

Hi,

our problem is in unit testing. When we deploy under Weblogic and use the Weblogic transaction manager, everything is ok.
But for unit testing, we use a LocalContainerEntityManagerFactoryBean with a HibernateJpaVendorAdapter injected into a JpaTransactionManager.

When isolation level other than DEFAULT is required for a transaction (setted through annotations), an InvalidIsolationLevelException is thrown.

I have solved this problem by writing a CustomHibernateJpaDialect in which I just delete the throw exception :

<i>
public class CustomHibernateJpaDialect
extends HibernateJpaDialect
{
public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition)
throws PersistenceException, SQLException,
TransactionException
{
entityManager.getTransaction().begin();
return null;
}

public void cleanupTransaction(Object transactionData) {
// This line throws a NullPointerException. Got no time to go deeper but we never change the flush mode so I let it commented
//((SessionTransactionData) transactionData).resetFlushMode();
}
}
</i>

and a CustomHibernateJpaVendorAdapter in which I use my new CustomHibernateJpaDialect :

<i>
public class CustomHibernateJpaVendorAdapter extends AbstractJpaVendorAdapter
{
private final PersistenceProvider persistenceProvider = new HibernatePersistence();

private final JpaDialect jpaDialect = new CustomHibernateJpaDialect();

public PersistenceProvider getPersistenceProvider() {
return this.persistenceProvider;
}

public Map getJpaPropertyMap() {
Properties jpaProperties = new Properties();

if (getDatabasePlatform() != null) {
  jpaProperties.setProperty(Environment.DIALECT, getDatabasePlatform());
}
else if (getDatabase() != null) {
  Class databaseDialectClass = determineDatabaseDialectClass(getDatabase());
  if (databaseDialectClass != null) {
    jpaProperties.setProperty(Environment.DIALECT, databaseDialectClass.getName());
  }
}

if (isGenerateDdl()) {
  jpaProperties.setProperty(Environment.HBM2DDL_AUTO, "update");
}
if (isShowSql()) {
  jpaProperties.setProperty(Environment.SHOW_SQL, "true");
}

return jpaProperties;

}

/**

  • Determine the Hibernate database dialect class for the given target database.
  • @param database the target database
  • @return the Hibernate database dialect class, or <code>null<code> if none found
    */
    protected Class determineDatabaseDialectClass(Database database) {
    switch (database) {
    case DB2: return DB2Dialect.class;
    case HSQL: return HSQLDialect.class;
    case INFORMIX: return InformixDialect.class;
    case MYSQL: return MySQLDialect.class;
    case ORACLE: return Oracle9Dialect.class;
    case POSTGRESQL: return PostgreSQLDialect.class;
    case SQL_SERVER: return SQLServerDialect.class;
    case SYBASE: return SybaseDialect.class;
    default: return null;
    }
    }

public Class<? extends EntityManager> getEntityManagerInterface() {
return HibernateEntityManager.class;
}

public JpaDialect getJpaDialect() {
return this.jpaDialect;
}
}
</i>

I can't believe it's all we have to do to make it work correctly but I can go ahead in my unit testing.

Is my isolation level really set (I want SERIALIZABLE) ?

Thank you


Affects: 2.5.2

Issue Links:

6 votes, 11 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions