java - 配置 Spring 事务或 EJB CMT

标签 java spring hibernate spring-data-jpa

我尝试使用 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的正确方法是什么? 我需要以不同的方式使用 Transaction 吗?

最佳答案

您正在使用@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。

关于java - 配置 Spring 事务或 EJB CMT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51464852/

相关文章:

spring - 对依赖于@OneToMany 集合的类进行单元测试

java - 未找到问题(请求的资源 [/CustomerManager/] 不可用)

java - org.springframework.dao.OptimisticLockingFailureException 与 hibernate 升级

java - 为 getStackTrace()[2].getMethodName() 获得不同的结果

java - Java 9-19 中生成自签名证书的 API 是什么?

java - 如何在普通java项目中使用maven项目jar

java - 使用 spring @Scheduled 的问题

java - 如何强制 Hibernate 在更新前删除孤儿

mysql - Hibernate 在 MySQL 上发出太多查询

java - Android 复选框组