Java SE 上的 JPA:对象:entity.Customer@5e80188f 不是已知的实体类型

Posted

技术标签:

【中文标题】Java SE 上的 JPA:对象:entity.Customer@5e80188f 不是已知的实体类型【英文标题】:JPA on Java SE: Object: entity.Customer@5e80188f is not a known entity type 【发布时间】:2013-10-27 14:18:25 【问题描述】:

我在关注

https://glassfish.java.net/javaee5/persistence/persistence-example.html

在 Java SE 环境中测试 JPA。 在 Eclipse 中,我:

创建了一个新的 JPA (2.1) 项目; 在options->JPA->Persistent class management,我选择了“Discover annotated classes automatically”而不是“Annotated classes must be listed in persistence.xml”。

我成功导入了 zip 文件 (Client.java Customer.java Order.java) 中的树 Java 类,并修改了 persistence.xml 文件以满足我的需要。但是在尝试执行 main 时出现以下错误。

[EL Info]: 2013-10-18 17:37:54.749--ServerSession(263489307)--EclipseLink, version: Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5
[EL Info]: connection: 2013-10-18 17:37:55.34--ServerSession(263489307)--file:/home/caterpillar/workspace/JPA_Java_SE/build/classes/_JPA_Java_SE login successful
[EL Warning]: metamodel: 2013-10-18 17:37:55.359--The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units.  Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
Exception in thread "main" java.lang.IllegalArgumentException: Object: entity.Customer@5e80188f is not a known entity type.
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4228)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:496)
    at client.Client.testInsert(Client.java:82)
    at client.Client.main(Client.java:49)

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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_1.xsd">
    <persistence-unit name="JPA_Java_SE">
        <properties>
            <property name="javax.persistence.logging.level" value="FINE"/>
            <property name="javax.persistence.logging.thread" value="false"/>
            <property name="javax.persistence.logging.session" value="false"/>
            <property name="javax.persistence.logging.timestamp" value="false"/>
            <property name="javax.persistence.logging.exceptions" value="false"/>

            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="password"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
        </properties>
    </persistence-unit>
</persistence>

项目目录树

$ tree
.
├── build
│   └── classes
│       ├── client
│       │   └── Client.class
│       ├── entity
│       │   ├── Customer.class
│       │   └── Order.class
│       └── META-INF
│           └── persistence.xml
├── sql
│   ├── tables_derby.sql
│   └── tables_oracle.sql
└── src
    ├── client
    │   └── Client.java
    ├── entity
    │   ├── Customer.java
    │   └── Order.java
    └── META-INF
        └── persistence.xml

10 directories, 10 files

所有类代码与http://glassfish.dev.java.net/javaee5/persistence/JPASE.zip 上的示例文件相同

【问题讨论】:

【参考方案1】:

persistence.xml 中缺少下一行:

<exclude-unlisted-classes>false</exclude-unlisted-classes>

这一行的放置方式如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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_1.xsd">
  <persistence-unit name="SamplePU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/sample"/>
      <property name="javax.persistence.jdbc.password" value="123"/>
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.user" value="root"/>
      <property name="eclipselink.logging.level" value="ALL"/>
      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

【讨论】:

我有一个与上面完全相同的persistence.xml(除了它是 Postgresql),但我仍然收到“在 Java SE 的实体搜索期间可能未找到模型类...”错误。我从 TestNG 测试运行它,因此它是一个 Java SE 环境。我怀疑 Eclipselink 根本没有在类路径中找到 @Entity 类。但为什么?应该找到它们。有人知道吗? 嗨,@Rogério 您在日志中看到有用的信息了吗? :-) 你好@PaulVargas 我刚刚发现它被怀疑,Eclipselink 根本不支持(还)在 Java SE 上查找实体类(它在 Java EE 上支持)。所以,我不得不将&lt;class&gt; 元素添加到我的persistence.xml 中;然后它工作正常。【参考方案2】:

还有另一个选项,类似于 Paul Vargas 提出的选项,也可以编辑 persistence.xml 文件。

如果您想更好地控制将哪些类作为实体进行管理, 使用:

&lt;exclude-unlisted-classes&gt;true&lt;/exclude-unlisted-classes&gt;

&lt;class&gt;YOUR CLASS CANNONICAL NAME&lt;/class&gt;

【讨论】:

我认为这是对OP问题的更正确答案,一个类没有在persistence.xml中明确声明,因此抛出异常。接受的答案是解决问题的一种方法。

以上是关于Java SE 上的 JPA:对象:entity.Customer@5e80188f 不是已知的实体类型的主要内容,如果未能解决你的问题,请参考以下文章

JPA之@Entity@Table@Column@Id

JPA之@Entity@Table@Column@Id

JPA之@Entity@Table@Column@Id

JPA的@Entity@Table@Column@Id

JPA的@Entity@Table@Column@Id

JPA的模式:从实体生成数据传输对象DTO并将DTO合并到数据库