问题描述
im正在使用Java进行项目。我的想法是在React Fr-End端使用Java作为后端来喂数据库。到目前为止,我已经准备好了后端
环境: IntellJ,Wildfly21,GitHub
上的项目启动wildfly并尝试保留实体时,在日志中总是看到 “原因:java.lang.IllegalArgumentException:未知实体:entities.Account”
这很有趣,因为如果我执行JUnit测试,则持久性可以完美地工作。 我可以通过在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="cLeverCore">
<description>Database connector</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>entities.Account</class>
<class>entities.AccountRole</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.MysqL.cj.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:MysqL://localhost:3306/cLeverCore" />
<property name="javax.persistence.jdbc.user" value="cLeverCoreManager" />
<property name="javax.persistence.jdbc.password" value="password123" />
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.allow_update_outside_transaction" value="true" />
<property name="hibernate.connection.autocommit" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MysqL5Dialect" />
<!-- Enable the logging of all the generated sql statements to the console -->
<property name="hibernate.show_sql" value="true" />
<!-- validate,update,create,create-drop,non -->
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.id.new_generator_mappings" value="false" />
</properties>
</persistence-unit>
</persistence>
我还添加了自动检测功能,希望可以自动检测到它们,但事实并非如此。有什么办法可以在启动时检测到所有@Entity类?我很确定肯定有一个我看不到的微小设置。
package entities;
import helper.PasswordHelper;
import javax.persistence.*;
import javax.ws.rs.QueryParam;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "account")
public class Account {
@Id
@GeneratedValue
@Column(name = "account_id",unique=true)
private int id;
@Column(nullable=false,unique=true)
@QueryParam("accountName")
private String accountName;
@Column(nullable=false)
@QueryParam("password")
private String password;
@ElementCollection
@CollectionTable(name = "account_role")
@Enumerated(EnumType.STRING)
private Set<AccountRole> accountRoles = new HashSet<AccountRole>();
public Account() {
}
public Account(String accountName,String password) {
this.accountName = accountName;
this.password = PasswordHelper.generatePassword(password);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getpassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<AccountRole> getAccountRoles() {
return accountRoles;
}
public void setAccountRoles(Set<AccountRole> accountRoles) {
this.accountRoles = accountRoles;
}
public void addAccountRole(AccountRole role) {
accountRoles.add(role);
}
public void removeAccountRole(AccountRole role) {
accountRoles.remove(role);
}
public void encryptPassowrt(String unhashedPass) {
this.password = PasswordHelper.generatePassword(unhashedPass);
}
public boolean isAuthorized(AccountRole role) {
return accountRoles.contains(AccountRole.ADMIN)
|| accountRoles.contains(role);
}
}
解决方法
persistence.xml
必须与所扫描的类位于同一jar /程序包/级别中,或者如果这些类位于单独的jar中,则必须在jar-file
标记之前列出它class
标签。如果您的persistence.xml
与最终类路径中的类分开放置,则必须列出每个带有MappedSuperclass
Embeddable
或Entity
注释的类。
您可以检查为EntityManagerFactory扫描的类路径,这不会更改解决方案。
我有一个帮助脚本可以做到这一点,因此我可以在测试中加载它们。
#!/bin/sh
grep -rEl '@(javax\.persistence\.)?(MappedSuperclass|Embeddable|Entity)' src/main/java/ | grep -oP '^[^\.]+' | LC_ALL=C sort | sed -e 's#/#.#g' | sed -re 's#^src.main.java.(.+)$# <class>\1</class>#'