Description
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:
- Isolation support for JPA with Hibernate EntityManager 4 [SPR-11942] #16559 Isolation support for JPA with Hibernate EntityManager 4
- How to implement Pessimistic Locking with JPA [SPR-3812] #8492 How to implement Pessimistic Locking with JPA
6 votes, 11 watchers