I'm trying to use spring-boot and hibernate. It works good when I use repositories, but I'm trying to get a Hibernate session to create a DAO, and this DAO is not being part of the transaction.
This is the test code:
Application.java
@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableTransactionManagement
public class Application implements CommandLineRunner {
@Autowired
private UserBusiness userBusiness;
@Autowired
@Bean(name="sessionFactory")
public SessionFactory sessionFactory(HibernateEntityManagerFactory factory) {
return factory.getSessionFactory();
}
@Override
public void run(String... arg0) throws Exception {
try {
userBusiness.createAdminUsers();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(userBusiness.listAll());
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args).close();
}
}
UserBusinessImpl.java:
@Service
public class UserBusinessImpl implements UserBusiness {
@Autowired
private UserRepository userRepository;
@Autowired
private UserDao userDao;
@Transactional(rollbackFor=Exception.class)
public void createAdminUsers() throws Exception {
userRepository.save(new User("User1", "u1", "123"));
userRepository.save(new User("User2", "u2", "123"));
userDao.test();
throw new Exception("Rollback");
}
public List<User> listAll() {
return userRepository.findAll();
}
}
UserRepository.java
public interface UserRepository extends JpaRepository<User, Long> {
}
UserDao:
@Repository
public class UserDao {
@Autowired
private SessionFactory sessionFactory;
public void teste() {
//current session does not exists and throws org.hibernate.HibernateException: No CurrentSessionContext configured!
// sessionFactory.getCurrentSession().save(new User("testDao", "dao", "123"));
sessionFactory.openSession().save(new User("testDao", "dao", "123"));
}
}
When I try to getCurrentSession() it throws me an error. and the openSession() is detached from my transaction so when Business throws and exception the Dao save is not rolled back. The two other inserts are rolled back.
How would be the correct way to get the currentSession in the DAO?
UPDATE: If I do a sessionFactory.openSession() it does not give any exception, but it's not part of the transaction.
If I try to use sessionFactory.getCurrentSession() that's the stacktrace:
org.hibernate.HibernateException: No CurrentSessionContext configured!
2014-09-26 11:00:28.488 TRACE 20938 --- [ main] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata@ff80080] for key [public abstract java.util.List org.springframework.data.jpa.repository.JpaRepository.findAll()] to thread [main]
2014-09-26 11:00:28.488 DEBUG 20938 --- [ main] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
2014-09-26 11:00:28.489 DEBUG 20938 --- [ main] o.s.orm.jpa.JpaTransactionManager : Opened new EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@62e8dbb0] for JPA transaction
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1010)
at org.sparta.hibernatetest.UserDao.teste(UserDao.java:35)
at org.sparta.hibernatetest.business.UserBusinessImpl.createAdminUsers(UserBusinessImpl.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy48.createAdminUsers(Unknown Source)
at org.sparta.hibernatetest.Application.run(Application.java:33)
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:677)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:695)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at org.sparta.hibernatetest.Application.main(Application.java:42)
Try this:
@Repository
public class UserDao {
@PersistenceContext
EntityManager entityManager;
protected Session getCurrentSession() {
return entityManager.unwrap(Session.class);
}
public void test() {
Session session = getCurrentSession();
session().save(new User("testDao", "dao", "123"));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With