JPA exception: Object: ... is not a known entity type
Asked Answered
U

11

18

I'm new to JPA and I'm having problems with the autogeneration of primary key values.

I have the following entity:

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

and the following main method in other class:

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

This is my persistence unit:

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

When I execute the program I get the following exception in the line marked with the proper comment:

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

What am I missing?

Urania answered 5/3, 2010 at 17:45 Comment(1)
I was override toString method and faced with a same method may it is because you are previously using this class without overriding toString method as my experienceInescutcheon
K
7

TopLink used to require you to explicitly set GenerationType.IDENTITY for MySQL, so change this and drop the database. Then try running your sample again. Further you might also want to explcitly set the database platform:

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

Also I vaguely remember that you have to run Toplink using its Java agent in order to make it function properly with a resource local entitymanager.

I did however successfully run your example using EclipseLink (which you should use since Toplink is outdated). Only cavat was that I did not have MySQL server handy, so I ran it using H2. I used the following Maven pom.xml to resolve the dependencies:

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

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

With these settings your code ran as expected.

Kynewulf answered 5/3, 2010 at 20:12 Comment(3)
the main diff that I see here is you have <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> to drop and create as opposed to just createBirchfield
Do you have any pointer on that toplink bug (because that would be a bug)?Appendicitis
I used Toplink Essentials with GlassFish back in 2007. In those days it mapped GenerationType.AUTO to GenerationType.TABLE (see 72.5.124.102/thread.jspa?messageID=10270235). So if you did not specifically use GenerationType.IDENTITY you had to have a sequence table handy. However I am not sure if this is still the case.Kynewulf
S
12

I ran into this same problem using NetBeans IDE 6.9.

Apparently, this is a known issue. See 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. Also see http://netbeans.org/bugzilla/show_bug.cgi?id=181068.

I added the last line below to persistence.xml and it fixed it for me.

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<!-- Add the following to work around exception issue -->
<exclude-unlisted-classes>false</exclude-unlisted-classes>
Schultz answered 9/4, 2011 at 22:41 Comment(1)
I don't know if this is a bug; I think considering as of 2018 it's still a thing, by now it's likely to be just something that the JPA spec is agnostic about. I needed to add this element (exclude-unlisted-classes) to a persistence.xml file that I had lifted from a working JPA project in Eclipse (which was using a combination of EclipseLink and Hibernate, going by the dependencies in the pom.xml) into a new bare-bones JPA project in IntelliJ that was only using EclipseLink (again, going by the dependencies in the pom.xml).Avuncular
C
10

As Charles pointed out in his answer, the problem is not the id generation, but the persistence layer not finding the entity.

As you, I am also new to JPA. I have tried to write a "Hello World" JPA application using org.eclipse.persistence.jpa.PersistenceProvider when I got this error. The mentioned workaround also worked for me. Moreover, through trial-error I also found that to declare your entities, you must always anotate @entity in each entity and:

  • if you set exclude-unlisted-classes to true, you also have to list the entities within class elements in your persistence.xml
  • if you set exclude-unlisted-classes to false the persistence layer can find the entities regardles of the class element in your persistence.xml.
Cassiani answered 9/5, 2011 at 12:12 Comment(1)
Writting a junit test with org.eclipse.persistence.jpa.PersistenceProvider I have also found that the @entity annotation is ignored and that I have to explicitly declare the classes to process. In other case, I also get the is not a known entity type.Cassiani
K
7

TopLink used to require you to explicitly set GenerationType.IDENTITY for MySQL, so change this and drop the database. Then try running your sample again. Further you might also want to explcitly set the database platform:

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

Also I vaguely remember that you have to run Toplink using its Java agent in order to make it function properly with a resource local entitymanager.

I did however successfully run your example using EclipseLink (which you should use since Toplink is outdated). Only cavat was that I did not have MySQL server handy, so I ran it using H2. I used the following Maven pom.xml to resolve the dependencies:

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

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

With these settings your code ran as expected.

Kynewulf answered 5/3, 2010 at 20:12 Comment(3)
the main diff that I see here is you have <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> to drop and create as opposed to just createBirchfield
Do you have any pointer on that toplink bug (because that would be a bug)?Appendicitis
I used Toplink Essentials with GlassFish back in 2007. In those days it mapped GenerationType.AUTO to GenerationType.TABLE (see 72.5.124.102/thread.jspa?messageID=10270235). So if you did not specifically use GenerationType.IDENTITY you had to have a sequence table handy. However I am not sure if this is still the case.Kynewulf
B
2

I use this syntax rather than type AUTO

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

Then, I use the simple type "long" for ID's with a lowercase l :

private long taskID;

This may be unrelated, but I also specify a different table name for my entities:

@javax.persistence.Entity(name = "Tasks")
public class Task implements Serializable
Birchfield answered 5/3, 2010 at 17:53 Comment(1)
Thanks, I tried all those but i keep getting the same exception (except that the message now says [id=0] instead of [id=null]).Urania
V
1

I ran into the same exception, when deploying web applications to GlassFish v3 (which uses EclipseLink as its JPA provider). I am not sure it's the same scenario as above - but the explanation for this bug in my case might help others :-) - turns out there's a bug in EclipseLink, when running under OSGi (which is the case in GlassFish), which leads EclipseLink to hold on to an "old" version of the entity class when re-deploying, resulting in this exception. The bug report is here.

Varden answered 2/4, 2010 at 18:7 Comment(0)
E
1

As far as I know, whenever I get this error, I just re-start glassfish. Works everytime.

Excitant answered 9/1, 2011 at 18:24 Comment(0)
R
1

if you are only getting this error in junit

try adding this in persistence.xml

<jar-file>file:../classes</jar-file>
Repent answered 3/12, 2014 at 23:24 Comment(0)
M
0

You could try and leave the definition out of the persistnce.xml The Persistence provider should than scan all classes in the classpath for @Entity annotations.

Marked answered 5/3, 2010 at 19:25 Comment(1)
Unless when used in J2SE mode in which case it is not a JPA requirement to scan the CLASSPATH, besides which "exclude-unlisted-classes" is not specified anywayAberration
B
0

I also have to add one other item to my persistence.xml when changing class/table defs so that the EM knows to build/update tables:

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

If I want a fresh start, I instead use:

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

I noticed that in your persistence.xml schema management is only set to "create tables" as opposed to drop/create, or update

Birchfield answered 5/3, 2010 at 20:26 Comment(0)
T
0

Check the class output folder of eclipse, sometimes you change the xml and it was not updated.

Thwack answered 16/1, 2012 at 16:36 Comment(0)
D
0

The combination of deployment from within NetBeans 8.2 on Glassfish 4.1 on a Maven project with the "Debug" function of a project can cause an outdated version to be re-deployed (unclear where the fault lies).

Stop GlassFish, delete [glassfish base]/glassfish/domains/[domain name]/generated/, restart and redeploy.

Duct answered 31/3, 2017 at 18:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.