JPA исключение: объект: ... не является известным типом объекта - PullRequest
13 голосов
/ 05 марта 2010

Я новичок в 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:...)

Чего мне не хватает?

Ответы [ 11 ]

7 голосов
/ 10 апреля 2011

Я столкнулся с этой же проблемой, используя IDE NetBeans 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>
6 голосов
/ 09 мая 2011

Как Чарльз указал в его ответ , проблема не в генерации идентификатора, а в уровне постоянства, не находящем сущность.

Как и вы, я тоже новичок в JPA. Я попытался написать JPA-приложение "Hello World", используя org.eclipse.persistence.jpa.PersistenceProvider, когда получил эту ошибку. Упомянутый обходной путь также работал для меня. Более того, методом проб и ошибок я также обнаружил, что для объявления своих сущностей необходимо всегда аннотировать @entity в каждой сущности и:

  • если вы установите exclude-unlisted-classes на true, вам также придется перечислить объекты в элементах class в вашем persistence.xml
  • , если вы установите exclude-unlisted-classes на false, слой персистентности может найти сущности относительно элемента class в вашем persistence.xml.
5 голосов
/ 05 марта 2010

TopLink раньше требовал от вас явной установки GenerationType.IDENTITY для MySQL, поэтому измените это и удалите базу данных. Затем попробуйте запустить ваш образец снова. Кроме того, вы также можете установить платформу базы данных:

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

Также я смутно помню, что вам нужно запустить Toplink, используя его Java-агент, чтобы заставить его функционировать должным образом с локальным менеджером сущностей ресурса.

Однако я успешно выполнил ваш пример, используя 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>

С этими настройками ваш код работал как положено.

2 голосов
/ 05 марта 2010

Я использую этот синтаксис вместо типа AUTO

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

Затем я использую простой тип "long" для идентификаторов со строчными буквами l:

private long taskID;

Это может быть не связано, но я также указываю другое имя таблицы для моих сущностей:

@javax.persistence.Entity(name = "Tasks")
public class Task implements Serializable
1 голос
/ 04 декабря 2014

, если вы получаете эту ошибку только в junit

, попробуйте добавить ее в persistence.xml

<jar-file>file:../classes</jar-file>
1 голос
/ 09 января 2011

Насколько я знаю, всякий раз, когда я получаю эту ошибку, я просто перезапускаю Glassfish.Работает каждый раз.

1 голос
/ 02 апреля 2010

Я столкнулся с тем же исключением при развертывании веб-приложений в GlassFish v3 (который использует EclipseLink в качестве поставщика JPA).Я не уверен, что это тот же сценарий, что и выше, - но объяснение этой ошибки в моем случае может помочь другим :-) - оказывается, есть ошибка в EclipseLink при работе под OSGi (как в GlassFish), котораяEclipseLink для удержания «старой» версии класса сущностей при повторном развертывании, что приводит к этому исключению.Отчет об ошибке здесь .

0 голосов
/ 31 марта 2017

Комбинация развертывания изнутри NetBeans 8.2 на Glassfish 4.1 в проекте Maven с функцией «Отладка» проекта может привести к повторному развертыванию устаревшей версии (неясно, в чем причина ошибки).

Остановите GlassFish, удалите [glassfish base]/glassfish/domains/[domain name]/generated/, перезапустите и повторно разверните.

0 голосов
/ 16 января 2012

Проверьте папку вывода класса eclipse, иногда вы изменяете xml, и он не обновлялся.

0 голосов
/ 05 марта 2010

Я также должен добавить еще один элемент в свой файл 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 установлено только "создание таблиц", а не удаление / создание или обновление

...