17

我是 JPA 的新手,我在自动生成主键值时遇到问题。

我有以下实体:

package jpatest.entities;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class MyEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    private String someProperty;

    public String getSomeProperty() {
        return someProperty;
    }

    public void setSomeProperty(String someProperty) {
        this.someProperty = someProperty;
    }

    public MyEntity() {
    }

    public MyEntity(String someProperty) {
        this.someProperty = someProperty;
    }

    @Override
    public String toString() {
        return "jpatest.entities.MyEntity[id=" + id + "]";
    }    
}

以及其他类中的以下主要方法:

public static void main(String[] args) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPATestPU");
    EntityManager em = emf.createEntityManager();

    em.getTransaction().begin();

    MyEntity e = new MyEntity("some value");    
    em.persist(e); /* (exception thrown here) */

    em.getTransaction().commit();

    em.close();
    emf.close();
}

这是我的持久性单元:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="JPATestPU" transaction-type="RESOURCE_LOCAL">
    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
    <class>jpatest.entities.MyEntity</class>
    <properties>
      <property name="toplink.jdbc.user" value="..."/>
      <property name="toplink.jdbc.password" value="..."/>
      <property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/jpatest"/>
      <property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="toplink.ddl-generation" value="create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

当我执行程序时,在标有正确注释的行中出现以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: Object: jpatest.entities.MyEntity[id=null] is not a known entity type.
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:3212)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.persist(EntityManagerImpl.java:205)
        at jpatest.Main.main(Main.java:...)

我错过了什么?

4

11 回答 11

10

我在使用 NetBeans IDE 6.9 时遇到了同样的问题。

显然,这是一个已知问题。请参阅 http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_101:_20100218:_Descriptor.javaClass_is_null_on_a_container_EM_for_a_specific_case。另请参阅http://netbeans.org/bugzilla/show_bug.cgi?id=181068

我将下面的最后一行添加到 persistence.xml 并为我修复了它。

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<!-- Add the following to work around exception issue -->
<exclude-unlisted-classes>false</exclude-unlisted-classes>
于 2011-04-09T22:41:27.997 回答
9

正如查尔斯在他的回答中指出的那样,问题不在于 id 生成,而是持久层没有找到实体。

和你一样,我也是 JPA 的新手。org.eclipse.persistence.jpa.PersistenceProvider当我收到此错误时,我曾尝试编写一个“Hello World”JPA 应用程序。提到的解决方法也对我有用。此外,通过试错我还发现,要声明您的实体,您必须始终@entity在每个实体中进行注释,并且:

  • 如果你设置exclude-unlisted-classestrue,你还必须在你的元素中列出实体classpersistence.xml
  • 如果您设置exclude-unlisted-classesfalse持久层,则class可以在persistence.xml.
于 2011-05-09T12:12:13.530 回答
7

TopLink 曾经要求您为 MySQL 显式设置GenerationType.IDENTITY,因此更改此设置并删除数据库。然后尝试再次运行您的示例。此外,您可能还想明确设置数据库平台:

 <property name="toplink.platform.class.name" 
                    value="oracle.toplink.platform.database.MySQL4Platform"/>

另外我隐约记得,您必须使用其 Java 代理运行 Toplink 才能使其与资源本地实体管理器一起正常运行。

但是,我确实使用 EclipseLink 成功运行了您的示例(由于 Toplink 已过时,您应该使用它)。唯一需要注意的是我没有方便的 MySQL 服务器,所以我使用 H2 运行它。我使用以下 Maven pom.xml 来解决依赖关系:

 <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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.randompage</groupId>
    <artifactId>sandbox</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>
    <name>sandbox</name>
    <repositories>
        <repository>
            <id>EclipseLink Repo</id>
            <url>http://www.eclipse.org/downloads/download.php?r=1&amp;nf=1&amp;file=/rt/eclipselink/maven.repo</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>javax.persistence</artifactId>
            <version>2.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.0.0</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.2.130</version>
        </dependency>
    </dependencies>
</project>

这个persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="JPATestPU" transaction-type="RESOURCE_LOCAL">
        <provider>
            org.eclipse.persistence.jpa.PersistenceProvider
        </provider>
        <class>org.randompage.MyEntity</class>
        <properties>
            <property name="javax.persistence.jdbc.user" value="johndoe"/>
            <property name="javax.persistence.jdbc.password" value="secret"/>
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:~/.h2/testdb;FILE_LOCK=NO"/>
            <property name="eclipselink.ddl-generation" value="create-tables"/>
            <property name="eclipselink.logging.level" value="INFO"/>
        </properties>
    </persistence-unit>
</persistence>

使用这些设置,您的代码按预期运行。

于 2010-03-05T20:12:07.960 回答
2

我使用这种语法而不是键入 AUTO

@javax.persistence.Id
@javax.persistence.GeneratedValue(strategy = GenerationType.IDENTITY)

然后,我对带有小写 l 的 ID 使用简单类型“long”:

private long taskID;

这可能不相关,但我也为我的实体指定了不同的表名:

@javax.persistence.Entity(name = "Tasks")
public class Task implements Serializable
于 2010-03-05T17:53:52.657 回答
1

在将 Web 应用程序部署到 GlassFish v3(它使用 EclipseLink 作为其 JPA 提供程序)时,我遇到了同样的异常。我不确定它与上面的情况相同 - 但在我的情况下对这个错误的解释可能对其他人有帮助:-) - 结果表明,当在 OSGi 下运行时(在 GlassFish 中就是这种情况),EclipseLink 中存在一个错误,这会导致EclipseLink 在重新部署时保留实体类的“旧”版本,导致此异常。错误报告在这里

于 2010-04-02T18:07:16.057 回答
1

据我所知,每当我收到此错误时,我都会重新启动 glassfish。每次都有效。

于 2011-01-09T18:24:15.357 回答
1

如果您只在junit中收到此错误

尝试在persistence.xml中添加它

<jar-file>file:../classes</jar-file>
于 2014-12-03T23:24:45.583 回答
0

您可以尝试将定义保留在persistence.xml 之外。持久性提供程序应该扫描类路径中的所有类以查找@Entity 注释。

于 2010-03-05T19:25:27.950 回答
0

更改类/表定义时,我还必须在我的 persistence.xml 中添加另一项,以便 EM 知道构建/更新表:

<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction=&apos;refresh&apos;)"/>

如果我想要一个新的开始,我会使用:

<!--<property name="openjpa.jdbc.SynchronizeMappings"
                value="buildSchema(SchemaAction='dropDB,add')"/>
                -->

我注意到在您的 persistence.xml 模式管理中仅设置为“创建表”,而不是删除/创建或更新

于 2010-03-05T20:26:07.190 回答
0

检查eclipse的类输出文件夹,有时你更改了xml并且它没有更新。

于 2012-01-16T16:36:04.377 回答
0

在 Maven 项目上的 Glassfish 4.1 上的 NetBeans 8.2 内部署与项目的“调试”功能相结合可能会导致重新部署过时的版本(不清楚故障所在)。

停止 GlassFish、删除[glassfish base]/glassfish/domains/[domain name]/generated/、重新启动并重新部署。

于 2017-03-31T18:36:18.190 回答