改为配置Spring事务或EJB CMT



我尝试用Hibernate配置Spring Boot:

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import org.datalis.plugin.database.dao.TerminalsService;
import org.datalis.plugin.database.models.TerminalsModel;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Qualifier("terminalsService")
public class TerminalsDaoHibernate implements TerminalsService {
@Autowired
private EntityManager entityManager;
@Override
@Transactional
public TerminalsModel getTerminalToken(String terminalToken) throws Exception {
TerminalsModel terminal = null;
Session session = entityManager.unwrap(Session.class);
try {
entityManager.getTransaction().begin();
terminal = (TerminalsModel) session.get(TerminalsModel.class, terminalToken);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
throw new Exception("Error");
}
return terminal;
}
}

但我得到了这个错误:

14:47:34,323 ERROR [stderr] (default task-1) java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
14:47:34,323 ERROR [stderr] (default task-1)    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:255)

正确配置@Transactional的正确方法是什么?我需要使用不同的交易方式吗?

您正在使用@Transactional,但仍在尝试手动启动事务。要么进行手动事务管理(即删除@Transactional(,要么通过删除手动事务管理代码来接受@Transactional

@Override
@Transactional
public TerminalsModel getTerminalToken(String terminalToken) throws Exception {
TerminalsModel terminal = null;
Session session = entityManager.unwrap(Session.class);
return (TerminalsModel) session.get(TerminalsModel.class, terminalToken);
}

然而,我不明白你为什么要在这里使用纯Hibernate而不是JPA。使用JPA可以获得相同的结果。

@Override
@Transactional
public TerminalsModel getTerminalToken(String terminalToken) throws Exception {
return entityManager.find(TerminalsModel.class, terminalToken);
}

一般来说,对于JPA API的当前状态,不需要在JPA上使用普通的Hibernate API。

最新更新