EntityManager.persist 没有任何作用
EntityManager.persist does not have any effect
我正在使用 Java EE 开发 API (JAXRS) 并尝试实施 JPA。为此,据我所知,我正在使用 EclipseLink,并且我的应用程序部署在 Payara 服务器上。
当我尝试使用 EntityManager 中的持久化方法时,没有任何反应,也没有错误消息或其他内容。
这是我的 DAO class:
package shareloc.model.dao;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Optional;
import static shareloc.ServletContextListenerImpl.createEntityManager;
public abstract class DAO<T> {
@PersistenceContext(unitName = "MariaDB")
protected EntityManager em;
private Class<T> entityClass;
public DAO(Class<T> entityClass) {
this.entityClass = entityClass;
this.em = getEntityManager();
}
private EntityManager getEntityManager() {
if (em == null) {
em = createEntityManager();
}
return em;
}
public T create(T entity) {
em.persist(entity);
return entity;
}
public void update(T entity) {
em.merge(entity);
}
public void delete(T entity) {
em.remove(em.merge(entity));
}
public Optional<T> findById(Object id) {
return Optional.ofNullable(em.find(entityClass, id));
}
public List<T> findAll() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(entityClass);
Root<T> root = cq.from(entityClass);
cq.select(root);
return em.createQuery(cq).getResultList();
}
}
EJB 用户:
package shareloc.ejb;
import javax.persistence.*;
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private int userId;
@Column(name = "pseudo")
private String pseudo;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "firstname")
private String firstname;
@Column(name = "lastname")
private String lastname;
public User() {}
public User(String pseudo, String email, String password, String firstname, String lastname) {
this.pseudo = pseudo;
this.email = email;
this.password = password;
this.firstname = firstname;
this.lastname = lastname;
}
public User(int userId, String pseudo, String email, String password, String firstname, String lastname) {
this.userId = userId;
this.pseudo = pseudo;
this.email = email;
this.password = password;
this.firstname = firstname;
this.lastname = lastname;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getPseudo() {
return pseudo;
}
public void setPseudo(String pseudo) {
this.pseudo = pseudo;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
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;
}
}
调用DAO Create方法的方法:
public static HashMap<String, String> register(String email, String pseudo, String password, String firstname, String lastname) {
HashMap<String, String> formError = new HashMap<>();
formError.putAll(checkEmail(email));
formError.putAll(checkPassword(password));
formError.putAll(checkPseudo(pseudo));
formError.putAll(checkFirstname(firstname));
formError.putAll(checkLastname(lastname));
if (formError.isEmpty()) {
System.out.println("form error empty test");
userDAO.create(new User(pseudo, email, password, firstname, lastname));
}
return formError;
}
认证根:
@POST
@Path("register")
@Produces(MediaType.APPLICATION_JSON)
public Response register(@QueryParam("email") String email, @QueryParam("pseudo") String pseudo,
@QueryParam("password") String password, @QueryParam("firstname") String firstname,
@QueryParam("lastname") String lastname) {
HashMap<String, String> errorMsgs = AuthManager.register(email, pseudo, password, firstname, lastname);
if (errorMsgs.isEmpty()) {
return Response.ok().build();
} else {
GenericEntity<HashMap<String, String>> entity =
new GenericEntity<>(errorMsgs) {};
return Response.status(Response.Status.BAD_REQUEST).entity(entity).build();
}
}
创建一个销毁em Factory的ServletContextListener:
@WebListener
public class ServletContextListenerImpl implements ServletContextListener {
private static EntityManagerFactory emf;
// Application start-up
@Override
public void contextInitialized(ServletContextEvent sce) {
emf = Persistence.createEntityManagerFactory("MariaDB");
}
// Application destroyed
@Override
public void contextDestroyed(ServletContextEvent sce) {
emf.close();
}
public static EntityManager createEntityManager() {
if (emf == null)
throw new NullPointerException("Context is not initialized yet.");
return emf.createEntityManager();
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.unistra.iutrs</groupId>
<artifactId>ShareLoc-API</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ShareLoc-API</name>
<packaging>war</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<junit.version>5.6.2</junit.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.eclipse.persistence/org.eclipse.persistence.jpa -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>3.0.0-M1</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.mvc</groupId>
<artifactId>javax.mvc-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
persistence.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name="MariaDB" transaction-type="JTA">
<jta-data-source>java:global/mariadb</jta-data-source>
<properties>
<property name="javax.persistence.transactionType" value="JTA"/>
<property name="javax.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mariadb://mysql.iutrs.unistra.fr:3306/sharelocda" />
<property name="javax.persistence.jdbc.user" value="" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="eclipselink.target-database" value="MySQL"/>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
</properties>
</persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<data-source>
<name>java:global/mariadb</name>
<class-name>org.mariadb.jdbc.MariaDbDataSource</class-name>
<server-name>mysql.iutrs.unistra.fr</server-name>
<port-number>3306</port-number>
<database-name>sharelocda</database-name>
<user></user>
<password></password>
</data-source>
<listener>
<listener-class>
shareloc.ServletContextListenerImpl
</listener-class>
</listener>
</web-app>
而且,这是来自 Payara 的日志:
[2020-11-14T17:38:44.418+0100] [Payara 5.2020.5] [WARNING] [] [javax.enterprise.resource.resourceadapter.org.glassfish.jdbc.deployer] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371924418] [levelValue: 900] [[
Value of maxPoolSize Given, -1, was outside the bounds, default value of 32 will be used - PLEASE UPDATE YOUR VALUE]]
[2020-11-14T17:38:44.419+0100] [Payara 5.2020.5] [WARNING] [] [javax.enterprise.resource.resourceadapter.org.glassfish.jdbc.deployer] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371924419] [levelValue: 900] [[
Value of steadyPoolSize Given, -1, was outside the bounds, default value of 8 will be used - PLEASE UPDATE YOUR VALUE]]
[2020-11-14T17:38:44.499+0100] [Payara 5.2020.5] [INFO] [] [org.eclipse.persistence.session./file:/D:/Utilisateurs/razor/Documents/Etudes/IUT/IUT Robert Schuman/LP CDAD/LP1 - Développement Service Web/ShareLoc-API/target/ShareLoc-API-1.0-SNAPSHOT/WEB-INF/classes/_MariaDB] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371924499] [levelValue: 800] [[
EclipseLink, version: Eclipse Persistence Services - 2.7.7.payara-p2]]
[2020-11-14T17:38:45.791+0100] [Payara 5.2020.5] [INFO] [] [fish.payara.micro.cdi.extension.ClusteredCDIEventBusImpl] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371925791] [levelValue: 800] [[
Clustered CDI Event bus initialized]]
[2020-11-14T17:38:45.856+0100] [Payara 5.2020.5] [INFO] [] [org.glassfish.soteria.servlet.SamRegistrationInstaller] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371925856] [levelValue: 800] [[
Initializing Soteria 1.1-b01.payara-p5 for context '/ShareLoc-API-1.0-SNAPSHOT']]
[2020-11-14T17:38:45.947+0100] [Payara 5.2020.5] [INFO] [jsf.config.listener.version] [javax.enterprise.resource.webcontainer.jsf.config] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371925947] [levelValue: 800] [[
Initializing Mojarra |version.string| for context '/ShareLoc-API-1.0-SNAPSHOT']]
[2020-11-14T17:38:46.062+0100] [Payara 5.2020.5] [FINE] [] [org.eclipse.persistence.default] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371926062] [levelValue: 500] [[
SAXParserFactory instance: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl@72289c40]]
[2020-11-14T17:38:46.114+0100] [Payara 5.2020.5] [INFO] [AS-WEB-GLUE-00172] [javax.enterprise.web] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371926114] [levelValue: 800] [[
Loading application [ShareLoc-API-1.0-SNAPSHOT] at [/ShareLoc-API-1.0-SNAPSHOT]]]
[2020-11-14T17:38:46.147+0100] [Payara 5.2020.5] [INFO] [] [javax.enterprise.system.core] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371926147] [levelValue: 800] [[
ShareLoc-API-1.0-SNAPSHOT was successfully deployed in 2 990 milliseconds.]]
[2020-11-14T17:39:01.341+0100] [Payara 5.2020.5] [FINE] [] [org.eclipse.persistence.session./file:/D:/Utilisateurs/razor/Documents/Etudes/IUT/IUT Robert Schuman/LP CDAD/LP1 - Développement Service Web/ShareLoc-API/target/ShareLoc-API-1.0-SNAPSHOT/WEB-INF/classes/_MariaDB.sql] [tid: _ThreadID=111 _ThreadName=http-thread-pool::http-listener-1(4)] [timeMillis: 1605371941341] [levelValue: 500] [[
SELECT user_id, email, firstname, lastname, password, pseudo FROM user WHERE (email = ?)
bind => [test@gmail.fr]]]
[2020-11-14T17:39:01.429+0100] [Payara 5.2020.5] [INFO] [] [] [tid: _ThreadID=111 _ThreadName=http-thread-pool::http-listener-1(4)] [timeMillis: 1605371941429] [levelValue: 800] [[
form error empty test]]
所以,没有例外,没有什么可以解释我做错了什么。问之前上网查了一下,发现有人有同样的问题,但是没有解决办法解决我的问题...
如果有人能解决我的问题,我会很高兴! (因为我的天啊,我在学习Java EE lol时遇到了很多问题)
如果您需要更多信息或代码,请告诉我!
谢谢!
编辑
public class AuthManager {
private static UserDAO userDAO = new UserDAO(); // I'm calling my DAO with this.
public static HashMap<String, String> register(String email, String pseudo, String password, String firstname, String lastname) {
HashMap<String, String> formError = new HashMap<>();
// Some check about the email, pseudo, etc..
if (formError.isEmpty()) {
System.out.println("form error empty test");
userDAO.create(new User(pseudo, email, password, firstname, lastname)); // That the create method from the DAO wihch only do a em.persist
}
return formError;
}
这是我的 UserDAO class:
public class UserDAO extends DAO<User> {
public UserDAO() {
super(User.class);
}
@Transactional
public Optional<User> findByEmail(String email) {
User user;
Query query = em.createQuery("SELECT u FROM User u WHERE u.email = :email");
query.setParameter("email", email);
try {
user = (User) query.getSingleResult();
return Optional.of(user);
} catch (NoResultException e) {
return Optional.empty();
}
}
}
DAO:
public abstract class DAO<T> {
@PersistenceContext(unitName = "MariaDB")
protected EntityManager em;
private Class<T> entityClass;
public DAO(Class<T> entityClass) {
this.entityClass = entityClass;
}
@Transactional
public T create(T entity) {
em.persist(entity);
return entity;
}
// + update, findAll, etc...
我很困惑。您是否已将持久性单元配置为指向由您的容器 (java:global/mariadb
) 管理的数据源 并且 配置了 JDBC 属性?你要拿定主意,要么使用容器提供的数据源,要么自己配置,但不能同时(换句话说,jta-data-source
属性 与 javax.persistence.jdbc.*
属性互斥)。
您收到错误是因为您已将持久性单元设置为使用 JTA,然后您正尝试使用 em.getTransaction()
在某处开始事务,这对于 JTA 是不允许的。此外,您将 @PersistenceContext
放在 entityManager
之上,这意味着在调用构造函数后,entityManager
可能会被注入的实例覆盖。
解决方案是,假设您 do 实际上想使用 JTA,使用 @PersistenceContext
注入 EntityManager
(您不必初始化它是手动的),然后用 @Transactional
注释你想自动执行的方法,而不是尝试使用 entityManager.getTransaction()
.
我正在使用 Java EE 开发 API (JAXRS) 并尝试实施 JPA。为此,据我所知,我正在使用 EclipseLink,并且我的应用程序部署在 Payara 服务器上。
当我尝试使用 EntityManager 中的持久化方法时,没有任何反应,也没有错误消息或其他内容。
这是我的 DAO class:
package shareloc.model.dao;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Optional;
import static shareloc.ServletContextListenerImpl.createEntityManager;
public abstract class DAO<T> {
@PersistenceContext(unitName = "MariaDB")
protected EntityManager em;
private Class<T> entityClass;
public DAO(Class<T> entityClass) {
this.entityClass = entityClass;
this.em = getEntityManager();
}
private EntityManager getEntityManager() {
if (em == null) {
em = createEntityManager();
}
return em;
}
public T create(T entity) {
em.persist(entity);
return entity;
}
public void update(T entity) {
em.merge(entity);
}
public void delete(T entity) {
em.remove(em.merge(entity));
}
public Optional<T> findById(Object id) {
return Optional.ofNullable(em.find(entityClass, id));
}
public List<T> findAll() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(entityClass);
Root<T> root = cq.from(entityClass);
cq.select(root);
return em.createQuery(cq).getResultList();
}
}
EJB 用户:
package shareloc.ejb;
import javax.persistence.*;
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private int userId;
@Column(name = "pseudo")
private String pseudo;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "firstname")
private String firstname;
@Column(name = "lastname")
private String lastname;
public User() {}
public User(String pseudo, String email, String password, String firstname, String lastname) {
this.pseudo = pseudo;
this.email = email;
this.password = password;
this.firstname = firstname;
this.lastname = lastname;
}
public User(int userId, String pseudo, String email, String password, String firstname, String lastname) {
this.userId = userId;
this.pseudo = pseudo;
this.email = email;
this.password = password;
this.firstname = firstname;
this.lastname = lastname;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getPseudo() {
return pseudo;
}
public void setPseudo(String pseudo) {
this.pseudo = pseudo;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
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;
}
}
调用DAO Create方法的方法:
public static HashMap<String, String> register(String email, String pseudo, String password, String firstname, String lastname) {
HashMap<String, String> formError = new HashMap<>();
formError.putAll(checkEmail(email));
formError.putAll(checkPassword(password));
formError.putAll(checkPseudo(pseudo));
formError.putAll(checkFirstname(firstname));
formError.putAll(checkLastname(lastname));
if (formError.isEmpty()) {
System.out.println("form error empty test");
userDAO.create(new User(pseudo, email, password, firstname, lastname));
}
return formError;
}
认证根:
@POST
@Path("register")
@Produces(MediaType.APPLICATION_JSON)
public Response register(@QueryParam("email") String email, @QueryParam("pseudo") String pseudo,
@QueryParam("password") String password, @QueryParam("firstname") String firstname,
@QueryParam("lastname") String lastname) {
HashMap<String, String> errorMsgs = AuthManager.register(email, pseudo, password, firstname, lastname);
if (errorMsgs.isEmpty()) {
return Response.ok().build();
} else {
GenericEntity<HashMap<String, String>> entity =
new GenericEntity<>(errorMsgs) {};
return Response.status(Response.Status.BAD_REQUEST).entity(entity).build();
}
}
创建一个销毁em Factory的ServletContextListener:
@WebListener
public class ServletContextListenerImpl implements ServletContextListener {
private static EntityManagerFactory emf;
// Application start-up
@Override
public void contextInitialized(ServletContextEvent sce) {
emf = Persistence.createEntityManagerFactory("MariaDB");
}
// Application destroyed
@Override
public void contextDestroyed(ServletContextEvent sce) {
emf.close();
}
public static EntityManager createEntityManager() {
if (emf == null)
throw new NullPointerException("Context is not initialized yet.");
return emf.createEntityManager();
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.unistra.iutrs</groupId>
<artifactId>ShareLoc-API</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ShareLoc-API</name>
<packaging>war</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<junit.version>5.6.2</junit.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.eclipse.persistence/org.eclipse.persistence.jpa -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>3.0.0-M1</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.mvc</groupId>
<artifactId>javax.mvc-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
persistence.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name="MariaDB" transaction-type="JTA">
<jta-data-source>java:global/mariadb</jta-data-source>
<properties>
<property name="javax.persistence.transactionType" value="JTA"/>
<property name="javax.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mariadb://mysql.iutrs.unistra.fr:3306/sharelocda" />
<property name="javax.persistence.jdbc.user" value="" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="eclipselink.target-database" value="MySQL"/>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
</properties>
</persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<data-source>
<name>java:global/mariadb</name>
<class-name>org.mariadb.jdbc.MariaDbDataSource</class-name>
<server-name>mysql.iutrs.unistra.fr</server-name>
<port-number>3306</port-number>
<database-name>sharelocda</database-name>
<user></user>
<password></password>
</data-source>
<listener>
<listener-class>
shareloc.ServletContextListenerImpl
</listener-class>
</listener>
</web-app>
而且,这是来自 Payara 的日志:
[2020-11-14T17:38:44.418+0100] [Payara 5.2020.5] [WARNING] [] [javax.enterprise.resource.resourceadapter.org.glassfish.jdbc.deployer] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371924418] [levelValue: 900] [[
Value of maxPoolSize Given, -1, was outside the bounds, default value of 32 will be used - PLEASE UPDATE YOUR VALUE]]
[2020-11-14T17:38:44.419+0100] [Payara 5.2020.5] [WARNING] [] [javax.enterprise.resource.resourceadapter.org.glassfish.jdbc.deployer] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371924419] [levelValue: 900] [[
Value of steadyPoolSize Given, -1, was outside the bounds, default value of 8 will be used - PLEASE UPDATE YOUR VALUE]]
[2020-11-14T17:38:44.499+0100] [Payara 5.2020.5] [INFO] [] [org.eclipse.persistence.session./file:/D:/Utilisateurs/razor/Documents/Etudes/IUT/IUT Robert Schuman/LP CDAD/LP1 - Développement Service Web/ShareLoc-API/target/ShareLoc-API-1.0-SNAPSHOT/WEB-INF/classes/_MariaDB] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371924499] [levelValue: 800] [[
EclipseLink, version: Eclipse Persistence Services - 2.7.7.payara-p2]]
[2020-11-14T17:38:45.791+0100] [Payara 5.2020.5] [INFO] [] [fish.payara.micro.cdi.extension.ClusteredCDIEventBusImpl] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371925791] [levelValue: 800] [[
Clustered CDI Event bus initialized]]
[2020-11-14T17:38:45.856+0100] [Payara 5.2020.5] [INFO] [] [org.glassfish.soteria.servlet.SamRegistrationInstaller] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371925856] [levelValue: 800] [[
Initializing Soteria 1.1-b01.payara-p5 for context '/ShareLoc-API-1.0-SNAPSHOT']]
[2020-11-14T17:38:45.947+0100] [Payara 5.2020.5] [INFO] [jsf.config.listener.version] [javax.enterprise.resource.webcontainer.jsf.config] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371925947] [levelValue: 800] [[
Initializing Mojarra |version.string| for context '/ShareLoc-API-1.0-SNAPSHOT']]
[2020-11-14T17:38:46.062+0100] [Payara 5.2020.5] [FINE] [] [org.eclipse.persistence.default] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371926062] [levelValue: 500] [[
SAXParserFactory instance: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl@72289c40]]
[2020-11-14T17:38:46.114+0100] [Payara 5.2020.5] [INFO] [AS-WEB-GLUE-00172] [javax.enterprise.web] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371926114] [levelValue: 800] [[
Loading application [ShareLoc-API-1.0-SNAPSHOT] at [/ShareLoc-API-1.0-SNAPSHOT]]]
[2020-11-14T17:38:46.147+0100] [Payara 5.2020.5] [INFO] [] [javax.enterprise.system.core] [tid: _ThreadID=125 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1605371926147] [levelValue: 800] [[
ShareLoc-API-1.0-SNAPSHOT was successfully deployed in 2 990 milliseconds.]]
[2020-11-14T17:39:01.341+0100] [Payara 5.2020.5] [FINE] [] [org.eclipse.persistence.session./file:/D:/Utilisateurs/razor/Documents/Etudes/IUT/IUT Robert Schuman/LP CDAD/LP1 - Développement Service Web/ShareLoc-API/target/ShareLoc-API-1.0-SNAPSHOT/WEB-INF/classes/_MariaDB.sql] [tid: _ThreadID=111 _ThreadName=http-thread-pool::http-listener-1(4)] [timeMillis: 1605371941341] [levelValue: 500] [[
SELECT user_id, email, firstname, lastname, password, pseudo FROM user WHERE (email = ?)
bind => [test@gmail.fr]]]
[2020-11-14T17:39:01.429+0100] [Payara 5.2020.5] [INFO] [] [] [tid: _ThreadID=111 _ThreadName=http-thread-pool::http-listener-1(4)] [timeMillis: 1605371941429] [levelValue: 800] [[
form error empty test]]
所以,没有例外,没有什么可以解释我做错了什么。问之前上网查了一下,发现有人有同样的问题,但是没有解决办法解决我的问题...
如果有人能解决我的问题,我会很高兴! (因为我的天啊,我在学习Java EE lol时遇到了很多问题) 如果您需要更多信息或代码,请告诉我! 谢谢!
编辑
public class AuthManager {
private static UserDAO userDAO = new UserDAO(); // I'm calling my DAO with this.
public static HashMap<String, String> register(String email, String pseudo, String password, String firstname, String lastname) {
HashMap<String, String> formError = new HashMap<>();
// Some check about the email, pseudo, etc..
if (formError.isEmpty()) {
System.out.println("form error empty test");
userDAO.create(new User(pseudo, email, password, firstname, lastname)); // That the create method from the DAO wihch only do a em.persist
}
return formError;
}
这是我的 UserDAO class:
public class UserDAO extends DAO<User> {
public UserDAO() {
super(User.class);
}
@Transactional
public Optional<User> findByEmail(String email) {
User user;
Query query = em.createQuery("SELECT u FROM User u WHERE u.email = :email");
query.setParameter("email", email);
try {
user = (User) query.getSingleResult();
return Optional.of(user);
} catch (NoResultException e) {
return Optional.empty();
}
}
}
DAO:
public abstract class DAO<T> {
@PersistenceContext(unitName = "MariaDB")
protected EntityManager em;
private Class<T> entityClass;
public DAO(Class<T> entityClass) {
this.entityClass = entityClass;
}
@Transactional
public T create(T entity) {
em.persist(entity);
return entity;
}
// + update, findAll, etc...
我很困惑。您是否已将持久性单元配置为指向由您的容器 (java:global/mariadb
) 管理的数据源 并且 配置了 JDBC 属性?你要拿定主意,要么使用容器提供的数据源,要么自己配置,但不能同时(换句话说,jta-data-source
属性 与 javax.persistence.jdbc.*
属性互斥)。
您收到错误是因为您已将持久性单元设置为使用 JTA,然后您正尝试使用 em.getTransaction()
在某处开始事务,这对于 JTA 是不允许的。此外,您将 @PersistenceContext
放在 entityManager
之上,这意味着在调用构造函数后,entityManager
可能会被注入的实例覆盖。
解决方案是,假设您 do 实际上想使用 JTA,使用 @PersistenceContext
注入 EntityManager
(您不必初始化它是手动的),然后用 @Transactional
注释你想自动执行的方法,而不是尝试使用 entityManager.getTransaction()
.