2010-03-05 7 views
10

Jestem nowy w JPA i mam problemy z autogeneracją wartości klucza podstawowego.Wyjątek JPA: Obiekt: ... nie jest znanym typem jednostki

Mam następujące jednostki:

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 + "]"; 
    }  
} 

oraz następujące główne metody w innej klasy:

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(); 
} 

To jest moja jednostka Trwałość:

<?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> 

Kiedy I wykonanie program Otrzymuję następujący wyjątek w linii oznaczonej odpowiednim komentarzem:

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:...) 

Czego mi brakuje?

Odpowiedz

3

TopLink wymagał od ciebie jawnego ustawienia GenerationType.IDENTITY dla MySQL, więc zmień to i upuść bazę danych. Następnie spróbuj ponownie uruchomić próbkę. Dodatkowo można też chcą explcitly ustawić platformę bazy danych:

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

Także ja niejasno pamiętać, że trzeba uruchomić Toplink używając swojego agenta Java w celu uczynienia go właściwie funkcjonować z zasobów lokalnych EntityManager.

Udało mi się jednak uruchomić twój przykład za pomocą EclipseLink (którego powinieneś użyć, ponieważ Toplink jest nieaktualny). Jedyne, że nie miałem serwera MySQL pod ręką, więc uruchomiłem go używając H2. Użyłem następujący Maven pom.xml rozwiązać zależności:

<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> 

i ten 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> 

z tymi ustawieniami kod biegnących zgodnie z oczekiwaniami.

+0

główną różnicą, którą tu widzę, jest upuszczać i tworzyć w przeciwieństwie do zwykłego tworzenia – Zak

+0

Dzięki to ustalono. Nadal jednak działa. –

+0

Czy masz jakiś wskaźnik tego błędu w toplink (ponieważ byłby to błąd)? –

2

używam tej składni zamiast typu AUTO

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

Następnie używam prostego typu "long" dla identyfikatorami z małymi L:

private long taskID; 

To może być związane, ale Podaj również inną nazwę tabeli dla moich podmiotów:

@javax.persistence.Entity(name = "Tasks") 
public class Task implements Serializable 
+0

Dzięki, wypróbowałem wszystkie te, ale nadal otrzymuję ten sam wyjątek (z wyjątkiem tego, że wiadomość teraz mówi [id = 0] zamiast [id = null]). – mmutilva

0

Możesz spróbować wyjść definicja z persistieve.xml Dostawca trwałości powinien niż skanować wszystkie klasy w ścieżce klas w przypadku adnotacji @Entity.

+1

O ile nie jest używany w trybie J2SE, w którym to przypadku * nie * wymaga JPA, aby przeskanować ścieżkę CLASSPATH, poza tym "nie wykluczam żadnych klas" exclude-unlisted-class " – DataNucleus

0

Muszę też dodać jeszcze jeden element do mojego persistence.xml przy zmianie DEFS klasa/stół tak, że EM wie zbudować/aktualizuj tabele:

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

Jeśli chcę nowy początek, to zamiast użyj:

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

Zauważyłem to w twojej wytrwałości.Zarządzanie schematem XML jest ustawione tylko na "tworzenie tabel" w przeciwieństwie do upuszczania/tworzenia lub aktualizowania

1

Wystąpił ten sam wyjątek podczas wdrażania aplikacji internetowych do GlassFish v3 (który używa EclipseLink jako dostawcy JPA). Nie jestem pewien, czy jest to ten sam scenariusz, co powyżej - ale wyjaśnienie tego błędu w moim przypadku może pomóc innym :-) - okazuje się, że w EclipseLink występuje błąd, działający pod OSGi (co jest w przypadku GlassFish), który prowadzi EclipseLink, aby zachować "starą" wersję klasy encji podczas ponownego wdrażania, powodując ten wyjątek. Raport o błędzie jest here.

1

O ile mi wiadomo, za każdym razem, gdy pojawia się ten błąd, po prostu rozpoczynam odświeżanie. Działa za każdym razem.

6

Wpadłem na ten sam problem, używając NetBeans IDE 6.9.

Podobno jest to znany problem. Zobacz 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. Zobacz także http://netbeans.org/bugzilla/show_bug.cgi?id=181068.

Dodałem ostatni wiersz poniżej do pliku persistence.xml i naprawiłem go dla mnie.

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
<!-- Add the following to work around exception issue --> 
<exclude-unlisted-classes>false</exclude-unlisted-classes> 
4

Jak Charles wskazał w his answer, problem nie jest wytwarzanie id, ale warstwa upór nie znalezienie podmiotu.

Jako Ty jestem również nowy w WZP. Próbowałem napisać aplikację WZP "Hello World" przy użyciu org.eclipse.persistence.jpa.PersistenceProvider, gdy otrzymałem ten błąd. Wspomniane obejście również zadziałało. Ponadto, poprzez próbny-błędu I również, że aby zadeklarować podmioty, trzeba zawsze anotate @entity w każdej jednostce oraz:

  • jeśli ustawisz exclude-unlisted-classes do true, trzeba także listy podmioty w class elementy twojej persistence.xml
  • jeśli ustawiony exclude-unlisted-classes do false warstwa trwałości może znajdować elementy odcisków elementu class w twoim persistence.xml.
+0

Pisząc ** junit ** test z ** 'org.eclipse.persistence.jpa.PersistenceProvider' ** Stwierdziłem również, że adnotacja' @ entity' jest ignorowana i że muszę ** jawnie zadeklarować klasy * * w procesie. W innym przypadku dostaję również 'nie jest znanym typem jednostki'. – Alberto

0

Sprawdź folder wyjściowy klasy zaćmienia, czasami zmieniasz plik XML i nie został on zaktualizowany.

1

jeśli otrzymujesz ten błąd tylko w JUnit

Spróbuj dodać ten w persistence.xml

<jar-file>file:../classes</jar-file> 
0

kombinacji rozmieszczenia od wewnątrz NetBeans 8.2 z GlassFish 4.1 na projekt Maven z „Debug "funkcja projektu może spowodować ponowne wdrożenie przestarzałej wersji (niejasne, gdzie leży usterka).

Zatrzymaj szklankęFish, usuń [glassfish base]/glassfish/domains/[domain name]/generated/, uruchom ponownie i przeprowadź ponowne wdrożenie.