La Transaction est nécessaire pour effectuer cette opération (soit utiliser une transaction ou à un contexte de persistance étendue)
Je suis l'aide de Wildfly 10.0.0 Final, Java EE7, Maven et JPA 2.1. Quand je suis interrogation de ma base de données pour les enregistrements, il fonctionne très bien et fait la liste de leurs employés, mais quand j'essaye de conserver un nouvel employé, il me donne l'exception suivante:
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)
...
Je suis en train de mettre en œuvre ce à l'aide de l'ACI et de CDI et les haricots. J'ai une source de données JTA, que j'ai configuré dans mon persistence.xml fichier:
<?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>
Le CDI haricot peut être vu ci-dessous. Il est relativement simple, il existe une méthode pour dresser la liste de 25 employés, et un autre qui devrait persister un employé spécifique:
@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)));
}
}
Les employés classe d'entité peut être trouvé ci-dessous:
@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;
}
}
Merci d'avance!
OriginalL'auteur masm64 | 2016-03-05
Vous devez vous connecter pour publier un commentaire.
Fondamentalement, on est en présence d'un container managed JTA conscient contexte de persistance avec bean géré transactions (BMT).
Donc, en plus de votre
EntityManager
vous devriez également injecter, dans votreDataFetchBean
, votreUserTransaction
, pour commencer, de valider ou d'annuler une transaction.Puis, dans votre
addEmployee
méthode, vous avez pour commencer, et ensuite valider votre transaction, de sorte que vos modifications à votre employé de l'entité peuvent être propagées à la base de données.En dépit de cela, vous devriez penser à la migration de la base de données des actions dans un EJB, l'injecter dans votre bean JSF, donc déléguant dans le conteneur de la charge de la gestion des transactions, c'est à dire faire usage de la CMT, au lieu de traiter manuellement.
Je vous suggère d'ouvrir une nouvelle question car avec seulement les infos fournies, il sera difficile de comprendre ce qui se passe.
je figgured nous utilisons une approche erronée dans nos applications, nous utilisons MangedBeans et un manuel déclenché EL de la FacesContext donc ce n'est pas possible d'injecter l'un usertransaction correctement. J'ai une grande solution pour ce.
Avez-vous besoin pour utiliser BMT? Sinon, vous pouvez déléguer à conteneurs, le fardeau de la preuve de la transaction, la gestion et l'utilisation de l'IMS. Une autre solution, prendre un coup d'oeil à @JohnAment de réponse.
Cela fonctionne aussi à l'intérieur d'un EJB (session ou d'un message-driven bean) si vous déléguez la gestion de la transaction pour le bean lui-même avec les annotations @TransactionManagement(TransactionManagementType.BEAN).
OriginalL'auteur aribeiro
Une autre façon de gérer cela est d'utiliser l'annotation
@Transactional
sur votreDataFetchBean
'méthodeaddEmployee
. Alors vous n'avez pas besoin de laUserTransaction
et peuvent utiliser des AOP à la gestion de la transaction.C'était une nouvelle fonctionnalité ajoutée dans JTA 1.2.
OriginalL'auteur John Ament
Vous pouvez voir ci-dessous le document sur la poignée de la transacion:
Container-Managed Transactions JEE6
utilisation
Transaction Attributes
en fonction de votre applicationOriginalL'auteur Alireza Alallah