hibernate - 执行此操作需要事务(使用事务或扩展持久性上下文)

标签 hibernate jpa jakarta-ee cdi managed-bean

我正在使用 Wildfly 10.0.0 Final、Java EE7、Maven 和 JPA 2.1。当我在数据库中查询记录时,它工作正常并列出了员工,但是当我尝试保留新员工时,它给了我以下异常:

javax.servlet.ServletException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
...

我正在尝试使用 JSF 和 CDI bean 来实现它。我有一个 JTA 数据源,已在我的 persistence.xml 文件中配置:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
    <persistence-unit name="MyPersistenceUnit">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>java:/EmployeesDS</jta-data-source>
        <class>com.home.entity.Employee</class>
        <properties>
            <property name="hibernate.archive.autodetection" value="class"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hbm2ddl.auto" value="update"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        </properties>
    </persistence-unit>
</persistence>

CDI bean 如下所示。相对简单,有一种方法可以列出 25 名员工,另一种方法应该持久化特定员工:
@Named
@RequestScoped
public class DataFetchBean {
    @PersistenceContext
    EntityManager em;

    public List getEmployees() {
        Query query = em.createNamedQuery("findEmployees");
        query.setMaxResults(25);
        return query.getResultList();
    }

    public String getEmployeeNameById(final int id) {
        addEmployee();

        Query query = em.createNamedQuery("findEmployeeNameById");
        query.setParameter("empno", id);
        Employee employee = (Employee) query.getSingleResult();
        return employee.getFirstName() + " " + employee.getLastName();
    }

    public void addEmployee() {
        em.persist(new Employee(500000, new Date(335077446), "Josh", "Carribean", 'm', new Date(335077446)));
    }
}

雇员实体类可以在下面找到:
@NamedQueries({
        @NamedQuery(
                name = "findEmployees",
                query = "select e from Employee e"
        ),           
        @NamedQuery(
                name = "findEmployeeNameById",
                query = "select e from Employee e where e.empNo = :empno"
        )
})
@Table(name = "employees")
public class Employee {
    @Id
    @Column(name = "emp_no")
    private int empNo;
    @Basic
    @Column(name = "birth_date")
    private Date birthDate;
    @Basic
    @Column(name = "first_name")
    private String firstName;
    @Basic
    @Column(name = "last_name")
    private String lastName;
    @Basic
    @Column(name = "gender")
    private char gender;
    @Basic
    @Column(name = "hire_date")
    private Date hireDate;

    public Employee() { }

    public int getEmpNo() {
        return empNo;
    }

    public void setEmpNo(int empNo) {
        this.empNo = empNo;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public Date getHireDate() {
        return hireDate;
    }

    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }

    public Employee(int empNo, Date birthDate, String firstName, String lastName, char gender, Date hireDate) {
        this.empNo = empNo;
        this.birthDate = birthDate;
        this.firstName = firstName;
        this.lastName = lastName;
        this.gender = gender;
        this.hireDate = hireDate;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Employee employee = (Employee) o;

        if (empNo != employee.empNo) return false;
        if (gender != employee.gender) return false;
        if (birthDate != null ? !birthDate.equals(employee.birthDate) : employee.birthDate != null) return false;
        if (firstName != null ? !firstName.equals(employee.firstName) : employee.firstName != null) return false;
        if (lastName != null ? !lastName.equals(employee.lastName) : employee.lastName != null) return false;
        if (hireDate != null ? !hireDate.equals(employee.hireDate) : employee.hireDate != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = empNo;
        result = 31 * result + (birthDate != null ? birthDate.hashCode() : 0);
        result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
        result = 31 * result + (int) gender;
        result = 31 * result + (hireDate != null ? hireDate.hashCode() : 0);
        return result;
    }
}

提前致谢!

最佳答案

另一种处理方法是使用注解 @Transactional在您的 DataFetchBean 上的方法addEmployee .那么你不需要 UserTransaction并且可以使用AOP来管理事务。

这是 JTA 1.2 中添加的新功能。

关于hibernate - 执行此操作需要事务(使用事务或扩展持久性上下文),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35808246/

相关文章:

java - 更新和/或删除时违反 Hibernate H2 引用完整性约束

java - 创建名称为 'CommunityService' 的 bean 时出错

java - 两个方法同时使用@Asynchronous注解

java - FacesContext.getCurrentInstance().addMessage 的自定义消息未显示在页面中 (JSF)

java - 如何处理maven下载的api中缺少的ExpressionFactory#newInstance()方法?

Hibernate Search + Infinispan + S3 -- 防止字母数字文件名

java - 当没有 main() 时如何知道应用程序从哪里启动?

java - 使用投影获取集合(hibernate)

java - 从 @EmbeddedId 类中提取父类(super class)时,实体没有持久性 id 属性

mysql - Spring Hibernate MySQL,MySQLSyntaxErrorException : table does not exist