我是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:...)
我缺少什么?
答案 0 :(得分:7)
我使用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>
答案 1 :(得分:6)
在Charles中指出his answer,问题不是id生成,而是持久层没有找到实体。
和你一样,我也是JPA的新手。当我收到此错误时,我尝试使用 org.eclipse.persistence.jpa.PersistenceProvider
编写“Hello World”JPA应用程序。上述解决方法对我也有用。此外,通过反复试验,我还发现,要声明您的实体,您必须始终在每个实体中加强@entity
并且:
exclude-unlisted-classes
设置为 true
,则还必须列出class
个元素中的实体您的persistence.xml
exclude-unlisted-classes
设置为 false
,则持久层可以找到您{中class
元素的实体 {1}}。答案 2 :(得分:5)
TopLink以前要求您为MySQL明确设置 GenerationType.IDENTITY ,因此请更改此设置并删除数据库。然后再次尝试运行您的样本。此外,您可能还想要explcitly设置数据库平台:
<property name="toplink.platform.class.name"
value="oracle.toplink.platform.database.MySQL4Platform"/>
我还清楚地记得你必须使用它的Java代理运行Toplink才能使它与资源本地实体管理器一起正常运行。
然而,我确实使用EclipseLink运行了您的示例(您应该使用它,因为Toplink已过时)。只有cavat是我没有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&nf=1&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>
使用这些设置,您的代码按预期运行。
答案 3 :(得分:2)
我使用此语法而不是键入AUTO
@javax.persistence.Id
@javax.persistence.GeneratedValue(strategy = GenerationType.IDENTITY)
然后,我使用简单类型“long”表示ID,并使用小写l:
private long taskID;
这可能不相关,但我还为我的实体指定了不同的表名:
@javax.persistence.Entity(name = "Tasks")
public class Task implements Serializable
答案 4 :(得分:1)
在将Web应用程序部署到GlassFish v3(使用EclipseLink作为其JPA提供程序)时,我遇到了同样的异常。我不确定它与上面的情况相同 - 但在我的情况下对这个错误的解释可能会帮助其他人:-) - 当在OSGi(在GlassFish中就是这种情况)下运行时,EclipseLink中存在一个错误EclipseLink在重新部署时保持实体类的“旧”版本,从而导致此异常。错误报告是here。
答案 5 :(得分:1)
据我所知,每当我收到此错误时,我就会重新启动glassfish。每次都有效。
答案 6 :(得分:1)
如果您只是在junit中收到此错误
尝试在persistence.xml中添加它
<jar-file>file:../classes</jar-file>
答案 7 :(得分:0)
您可以尝试将定义保留在persistnce.xml之外。持久性提供程序应该扫描类路径中的所有类以获取@Entity注释。
答案 8 :(得分:0)
在更改类/表defs时,我还必须向persistence.xml添加另一个项目,以便EM知道构建/更新表:
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction='refresh')"/>
如果我想重新开始,我会改用:
<!--<property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(SchemaAction='dropDB,add')"/>
-->
我注意到你的persistence.xml模式管理只设置为“创建表”而不是删除/创建或更新
答案 9 :(得分:0)
检查eclipse的类输出文件夹,有时你更改了xml并且没有更新。
答案 10 :(得分:0)
在Maven项目的Glassfish 4.1上的NetBeans 8.2中使用&#34; Debug&#34;进行部署的组合。项目的功能可能导致重新部署过时的版本(不清楚故障所在的位置)。
停止GlassFish,删除[glassfish base]/glassfish/domains/[domain name]/generated/
,重新启动并重新部署。