hi!
i got a simple test-application for finding out some differences in transaction-behavior between using native hibernate and the hibernate implementation of JPA because i want to switch an application from pure hibernate
to JPA 2.0
i made this tes app because, when using hibernate (sessionfactory/hibernatetransactionmanager) it is not necessary to put a @Transactional annotation to a method to persist an entity. in jpa (from hibernate) nothing will be persisted without the @Transactional
there is one config using hibernate SessionFactory and spring's HibernateTransactionManager both using the same datasource bean
the other config uses a LocalContainerEntityManagerFactoryBean and JPATransactionManager.
i also use the hibernate/jpa templates provided by spring for data access. these are used by a repository class and the repository class is accessed by a facade.
in the facade, i put a @Transactional annotation on the required methods. therefore i discovered confusing behavior.
here the methods i use in the tests:
method for testing the behavior:
facade method:Code:public void writeNewTestEntityToDB() { TestEntity te = new TestEntity(); te.setName("hi!"); te.setHistory(new EntityHistory(new Date(), 1L)); getFacade().saveTestEntity(te); getFacade().saveTestEntity(te); getFacade().saveTestEntity(te); }
repository method:Code:@Transactional public void saveTestEntity(TestEntity entity) { getTestRepository().saveTestEntity(entity); }
the genericDAO is either using JPATemplate or HibernateTemplate. both then use the corresponding *.merge(E entity) methodCode:public void saveTestEntity(TestEntity entity) { getGenericDAO().attach(entity); }
please note that the sessionfactory is using an IdTransferringMergeEventListener (the result in CASE 1 is not surprising but CASE 2 is)
CASE 1 with SESSIONFACTORY AND @Transactional on facade-method:
The entity just gets persisted one time.
hibernate output:
CASE 2 with SESSIONFACTORY and WITHOUT @Transactional on facade-method:Code:Hibernate: insert into TestEntity (id, createdBy, createdOn, updatedBy, updatedOn, myEnum, name) values (null, ?, ?, ?, ?, ?, ?) Hibernate: call identity() Hibernate: select testentity0_.id as ... Hibernate: select testentity0_.id as ...
There are three records in the db (which i expected as normal behavior)
hibernate output:
CASE 3 with EntityManagerFactory AND @Transactional on facade method:Code:Hibernate: insert into TestEntity (id, createdBy, createdOn, updatedBy, updatedOn, myEnum, name) values (null, ?, ?, ?, ?, ?, ?) Hibernate: call identity() Hibernate: insert into TestEntity (id, createdBy, createdOn, updatedBy, updatedOn, myEnum, name) values (null, ?, ?, ?, ?, ?, ?) Hibernate: call identity() Hibernate: insert into TestEntity (id, createdBy, createdOn, updatedBy, updatedOn, myEnum, name) values (null, ?, ?, ?, ?, ?, ?) Hibernate: call identity()
There are three records in the db.
hibernate output (same as in CASE 2):
CASE 4 with EntityManagerFactory and WITHOUT @Transactional on facade method:Code:Hibernate: insert into TestEntity (id, createdBy, createdOn, updatedBy, updatedOn, myEnum, name) values (null, ?, ?, ?, ?, ?, ?) Hibernate: call identity() Hibernate: insert into TestEntity (id, createdBy, createdOn, updatedBy, updatedOn, myEnum, name) values (null, ?, ?, ?, ?, ?, ?) Hibernate: call identity() Hibernate: insert into TestEntity (id, createdBy, createdOn, updatedBy, updatedOn, myEnum, name) values (null, ?, ?, ?, ?, ?, ?) Hibernate: call identity()
nothing is done here by hibernate. no output and no persisted objects.
CASE 3 and CASE 4 behave like i expected them to, but i do not understand why HibernateTransactionManager does not need @Transactional and behaves kind of weird to me.
what are the differences here? it is really confusing me and i do not understand why it is behaving this way.
can anyone please help me out?
thanks a lot!
chris


Reply With Quote