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

我正在使用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;

}

}

提前致谢!

回答:

基本上,一种情况是存在带有Bean管理事务(BMT)的容器管理的JTA感知持久性上下文。

因此,除了你的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中,然后将其注入到JSF bean中,因此将管理事务的责任委托给了容器,即使用CMT,而不是手动处理事务。

以上是 需要事务才能执行此操作(使用事务或扩展的持久性上下文) 的全部内容, 来源链接: utcz.com/qa/409244.html

回到顶部