Исключение JPA: Object:... не является известным типом объекта
Я новичок в 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:...)
Что мне не хватает?
Ответы
Ответ 1
Для 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&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>
С этими настройками ваш код работает так, как ожидалось.
Ответ 2
Я столкнулся с этой же проблемой, используя 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>
Ответ 3
Как Charles указал в его ответ, проблема не в генерации идентификаторов, а в слой сохранения не обнаруживает объект.
Как вы, я также новичок в JPA. Я попытался написать приложение "Hello World" JPA, используя org.eclipse.persistence.jpa.PersistenceProvider
, когда я получил эту ошибку. Указанное обходное решение также сработало для меня. Более того, посредством пробной ошибки я также обнаружил, что для объявления ваших объектов вы должны всегда анотировать @entity
в каждом объекте и:
- если вы установите
exclude-unlisted-classes
на true
, вы также должны перечислить сущности внутри элементов class
в persistence.xml
- если вы установите
exclude-unlisted-classes
на false
, уровень персистентности может найти объекты для элементов class
в вашем persistence.xml
.
Ответ 4
Я использую этот синтаксис, а не тип 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
Ответ 5
Я столкнулся с тем же исключением при развертывании веб-приложений в GlassFish v3 (который использует EclipseLink в качестве своего провайдера JPA). Я не уверен, что это тот же самый сценарий, что и выше, но объяснение этой ошибки в моем случае может помочь другим:-) - появляется ошибка в EclipseLink при работе под OSGi (что имеет место в GlassFish), что приводит EclipseLink удерживает "старую" версию класса сущности при повторном развертывании, что приводит к этому исключению. Отчет об ошибке - здесь.
Ответ 6
Насколько я знаю, всякий раз, когда я получаю эту ошибку, я просто начинаю старую рыбку. Работает каждый раз.
Ответ 7
если вы только получаете эту ошибку в junit
попробуйте добавить это в файл persistence.xml
<jar-file>file:../classes</jar-file>
Ответ 8
Вы можете попытаться оставить определение из persistnce.xml Поставщику Persistence необходимо, чем сканировать все классы в pathpath для аннотаций @Entity.
Ответ 9
Мне также нужно добавить один другой элемент в мой persistence.xml при изменении класса/таблицы defs, чтобы EM знал, как создавать/обновлять таблицы:
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction='refresh')"/>
Если я хочу начать новый старт, вместо этого я использую:
<!--<property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(SchemaAction='dropDB,add')"/>
-->
Я заметил, что в вашем управлении конфигурацией persistence.xml установлено только "создавать таблицы" в отличие от drop/create или update
Ответ 10
Проверьте выходную папку класса eclipse, иногда вы меняете xml и не обновляетесь.
Ответ 11
Комбинация развертывания из NetBeans 8.2 на Glassfish 4.1 в проекте Maven с функцией "Отладка" проекта может привести к повторной развертке устаревшей версии (непонятно, где ошибка).
Остановите GlassFish, удалите [glassfish base]/glassfish/domains/[domain name]/generated/
, перезапустите и повторно разверните.