问题:
entityManager.unwrap(SessionImplementor.class)
导致no transactional entitymanager available
异常。
代码:
@Component
public class HibernateEventWiring {
@Autowired
private ViewListener listener;
@PersistenceContext(unitName = "config-punit")
private EntityManager entityManager;
@PostConstruct
public void registerListeners() {
SessionFactory sessionFactory = getSessionFactory();
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(
EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener(listener);
}
@Transactional
private SessionFactory getSessionFactory() {
// EXCEPTION: No transactional entitymanager available
return entityManager.unwrap(SessionImplementor.class).getFactory();
}
}
根据这个优秀的答案:
在@PostConstruct(与InitializingBean接口中的afterPropertiesSet一样)中,无法确保所有后处理都已完成,因此(实际上)不能有事务。
正如我所见,您不需要事务,也不需要实体管理器 bean,而是需要实体管理器工厂 bean。我认为您应该简单地自动装配 EntityManagerFactory,然后从中解开 Hibernate SessionFactory。
@Autowired
private EntityManagerFactory entityManagerFactory;
@PostConstruct
public void registerListeners() {
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
...
}
在我的单元测试中初始化数据库对我来说是这样的:
@Autowired
private EntityManagerFactory entityManagerFactory;
@PostConstruct
public void initDb() {
Request request = new Request();
request.setAction("test action");
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.persist(request);
em.flush();
transaction.commit();
}