私は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:...)
何が欠けていますか?
TopLinkでは、MySQLに対してGenerationType.IDENTITYを明示的に設定する必要があったため、これを変更してデータベースを削除しました。次に、もう一度サンプルを実行してみてください。さらに、データベースプラットフォームを明示的に設定することもできます。
<property name="toplink.platform.class.name"
value="Oracle.toplink.platform.database.MySQL4Platform"/>
また、リソースローカルのentitymanagerで正しく機能させるには、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&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>
これらの設定により、コードは期待どおりに実行されました。
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>
Charles が his answer で指摘したように、問題はIDの生成ではなく、永続層がエンティティを見つけられないことです。
あなたと同じように、私もJPAの初心者です。このエラーが発生したとき、org.Eclipse.persistence.jpa.PersistenceProvider
を使用して「Hello World」JPAアプリケーションを作成しようとしました。上記の回避策も私にとってはうまくいきました。さらに、試行錯誤の結果、エンティティを宣言するには常に各エンティティの@entity
に注釈を付けるおよび
exclude-unlisted-classes
をtrue
に設定する場合は、persistence.xml
のclass
要素内のエンティティをリストする必要もあります。exclude-unlisted-classes
をfalse
に設定した場合、永続化レイヤーはエンティティを見つけることができますpersistence.xml
のclass
要素の関連要素。タイプ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
junitでこのエラーが発生するだけの場合
これをpersistence.xmlに追加してみてください
<jar-file>file:../classes</jar-file>
GlassFish v3(JPAプロバイダーとしてEclipseLinkを使用)にWebアプリケーションをデプロイするときに、同じ例外が発生しました。上記と同じシナリオであるかどうかはわかりませんが、私の場合のこのバグの説明は他の人を助けるかもしれません:-)-OSGiで実行している場合(GlassFishの場合)、EclipseLinkにバグがあることが判明し、 EclipseLinkは、再デプロイ時にエンティティクラスの「古い」バージョンを保持するため、この例外が発生します。バグレポートは こちら です。
私の知る限り、このエラーが発生するたびに、Glassfishを再起動するだけです。いつでも動作します。
定義をpersistence.xmlから外してみてください。Persistenceプロバイダーは、@ Entityアノテーションのクラスパス内のすべてのクラスをスキャンする必要があります。
Eclipseのクラス出力フォルダーを確認してください。xmlを変更しても更新されない場合があります。
また、クラス/テーブルの定義を変更するときに、persistence.xmlに他のアイテムを1つ追加して、EMがテーブルを作成/更新できるようにする必要があります。
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction='refresh')"/>
やり直したい場合は、代わりに次を使用します。
<!--<property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(SchemaAction='dropDB,add')"/>
-->
私はあなたのpersistence.xmlでスキーマ管理がドロップ/作成または更新ではなく「テーブルを作成する」にのみ設定されていることに気付きました
MavenプロジェクトのGlassfish 4.1上のNetBeans 8.2内からのデプロイメントとプロジェクトの「デバッグ」機能の組み合わせにより、古いバージョンが再デプロイされる可能性があります(どこに障害があるか不明)。
GlassFishを停止して削除[glassfish base]/glassfish/domains/[domain name]/generated/
、再起動して再デプロイします。