Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 执行此操作需要事务(使用事务或扩展持久性上下文)_Hibernate_Jpa_Jakarta Ee_Cdi_Managed Bean - Fatal编程技术网

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

Hibernate 执行此操作需要事务(使用事务或扩展持久性上下文),hibernate,jpa,jakarta-ee,cdi,managed-bean,Hibernate,Jpa,Jakarta Ee,Cdi,Managed Bean,我使用的是Wildfly 10.0.0 Final、JavaEE7、Maven和JPA2.1。当我查询数据库中的记录时,它可以正常工作并列出员工,但当我尝试保留新员工时,它会给我以下异常: javax.servlet.ServletException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context) j

我使用的是Wildfly 10.0.0 Final、JavaEE7、Maven和JPA2.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和CDIBeans实现这一点。我有一个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>
员工实体类可在下面找到:

@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;
    }
}

提前谢谢

基本上,一个是存在一个容器管理的JTA感知持久性上下文和bean管理的事务(BMT)

因此,除了您的
EntityManager
之外,您还应该在
DataFetchBean
中注入您的
UserTransaction
,以便开始、提交或回滚事务

@Named
@RequestScoped
public class DataFetchBean {
    @PersistenceContext
    EntityManager em;

    @Resource
    private UserTransaction userTransaction;

    ...
}
然后,在
addEmployee
方法中,您必须开始并提交事务,这样您对员工实体的更改就可以传播到数据库中

public void addEmployee() throws Exception {
    Employee employee = new Employee(500000, new Date(335077446), "Josh", "Carribean", 'm', new Date(335077446));

    userTransaction.begin();
    em.persist(employee);
    userTransaction.commit();
}

尽管如此,您还是应该考虑将数据库操作迁移到EJB中,将其注入JSFbean,从而将管理事务的责任委托给容器,即使用CMT,而不是手动处理它们。

另一种处理方法是在
DataFetchBean
的方法
addEmployee
上使用注释
@Transactional
。这样您就不需要
UserTransaction
,可以使用AOP来管理事务

@Named
@RequestScoped
public class DataFetchBean {
    @PersistenceContext
    EntityManager em;

    @Resource
    private UserTransaction userTransaction;

    ...
}

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

您可以看到下面关于处理交易的文档:


使用
事务属性
基于您的应用程序

在您的方法上添加@Transactional注释它将使其成为“事务性的”

一种简单的方法,将
@Transactional(Transactional.TxType.REQUIRED)
添加到方法

我遇到了同样的问题,解决方案是

@Transactional(rollbackOn = Exception.class)

添加到Bean调用的方法中

这给了我“javax.resource.ResourceException:IJ000460:事务错误检查”“javax.persistence.PersistenceException:org.hibernate.exception.genericjdbception:无法获取JDBC连接”@StefanWendelmann,我建议你打开一个新问题,因为只有提供的信息很难理解发生了什么。我指出,我们在应用程序中使用了错误的方法,使用了MangedBeans和从FacesContext手动触发的EL,因此无法正确注入UserTransaction。我必须想出一个更大的解决方案。你需要使用BMT吗?否则,您可以将事务管理的责任委托给容器,并使用CMT。另一种选择是,看看@JohnAment的答案。如果您使用注释@TransactionManagement(TransactionManagementType.bean)将事务管理委托给bean本身,那么这也可以在EJB(会话或消息驱动bean)中工作。