My webapp (Spring3 + Hibernate3) always worked with services class-annotated with @Transactional and this configuration:
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
Now... I'm on Google AppEngine. For some nasty reason I don't know yet, @Transactional does not work. It uses some class in javax.naming, which is not whitelisted. It ends up with:
Error creating bean with name 'mySessionFactory': Post-processing of
the FactoryBean's object failed; nested exception is
java.lang.SecurityException: Unable to get members for class
org.hibernate.impl.SessionFactoryImpl
Please don't ask me why.... :-\
Using Spring's HibernateTemplate instead of my dao (which uses raw session factory) solved the problem, but I know it's a little obsolete.
So, I want to try using manual old style transactions. Questions:
- where? I'd like to keep the transactions in the service layer.
- how?
SessionFactoryImpl
dependency is not in Google App Engine whitelist. There is a number of Google hits discussing it.
As far as "what to do", you have options:
Depend on on another JPA provider
Don't use ORM at all, and go native with Spring's JdbcTemplate (my favorite)
I am not sure why you need to use a programmatic transaction management since Hibernate is the root of your problem, but if you just like to know how, here is a draft:
public class SomeService implements SomeInterface {
private SomeDao thisDaoWrapsJdbcTemplate;
private PlatformTransactionManager transactionManager;
public void setTransactionManager( PlatformTransactionManager transactionManager ) {
this.transactionManager = transactionManager;
}
public void doBusiness( Business: business ) {
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction( def );
try {
// do business here
Money money = Money.LOTS_OF
...
// wire the money in..
thisDaoWrapsJdbcTemplate.depositLotsOfMoney( money )
transactionManager.commit( status );
} catch ( DataAccessException dae ) {
transactionManager.rollback( status );
throw dae;
}
return;
}