EclipseLink error: Entity class has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass

StackOverflow https://stackoverflow.com/questions/10319387

Pergunta

I'm trying to get EclipseLink to work with Spring (MVC and spring-data) version 3.1.1 and I'm running to a problem right from the outset. The error below occurs on starting up Tomcat (v7.0). I've searched for the error but come up with very little and I'm not sure where to go next. There is some talk of this problem occurring when using interfaces with Entity classes but as you can see my User.java class extends nothing.

    Apr 25, 2012 5:18:34 PM org.apache.catalina.core.AprLifecycleListener init
    INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Java\jdk1.6.0_29\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Java/jdk1.5.0_22/bin/../jre/bin/server;C:/Java/jdk1.5.0_22/bin/../jre/bin;C:/Java/jdk1.5.0_22/bin/../jre/lib/amd64;C:\oracle\product\10.2.0\client_1\bin;C:\Java\jdk1.5.0_22\bin;c:\windows\system32;c:\windows;c:\windows\system32\wbem;c:\windows\system32\windowspowershell\v1.0\;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\Apache Software Foundation\apache-ant-1.7.0\bin;C:\Program Files\SlikSvn\bin\;C:\JAD;C:\Program Files\MySQL\MySQL Server 5.5\bin;C:\maven\apache-maven-3.0.4\bin;C:\eclipse;;.
    Apr 25, 2012 5:18:34 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
    WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:proxi' did not find a matching property.
    Apr 25, 2012 5:18:34 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler ["http-bio-8980"]
    Apr 25, 2012 5:18:34 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler ["ajp-bio-8909"]
    Apr 25, 2012 5:18:34 PM org.apache.catalina.startup.Catalina load
    INFO: Initialization processed in 842 ms
    Apr 25, 2012 5:18:34 PM org.apache.catalina.core.StandardService startInternal
    INFO: Starting service Catalina
    Apr 25, 2012 5:18:34 PM org.apache.catalina.core.StandardEngine startInternal
    INFO: Starting Servlet Engine: Apache Tomcat/7.0.22
    Apr 25, 2012 5:18:35 PM org.apache.catalina.core.ApplicationContext log
    INFO: Initializing Spring root WebApplicationContext
    INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
    INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Wed Apr 25 17:18:35 CEST 2012]; root of context hierarchy
    INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/root-context.xml]
    INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@e8ae59a: defining beans [userService,entityManagerFactory,dataSource,txManager]; root of factory hierarchy
    INFO : org.springframework.jdbc.datasource.DriverManagerDataSource - Loaded JDBC driver: org.hsqldb.jdbcDriver
    INFO : org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Building JPA container EntityManagerFactory for persistence unit 'default'
    [EL Config]: 2012-04-25 17:18:36.484--ServerSession(1353906974)--Thread(Thread[Thread-2,5,main])--The access type for the persistent class [class com.proxi.user.User] is set to [FIELD].
    [EL Config]: 2012-04-25 17:18:36.552--ServerSession(1353906974)--Thread(Thread[Thread-2,5,main])--The alias name for the entity class [class com.proxi.user.User] is being defaulted to: User.
    INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@e8ae59a: defining beans [userService,entityManagerFactory,dataSource,txManager]; root of factory hierarchy
    ERROR: org.springframework.web.context.ContextLoader - Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/spring/root-context.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.EntityManagerSetupException
    Exception Description: Predeployment of PersistenceUnit [default] failed.
    Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException
    Exception Description: Entity class [class com.proxi.user.User] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
    Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.EntityManagerSetupException
    Exception Description: Predeployment of PersistenceUnit [default] failed.
    Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException
    Exception Description: Entity class [class com.proxi.user.User] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
        at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1127)
        at org.eclipse.persistence.jpa.PersistenceProvider.createContainerEntityManagerFactory(PersistenceProvider.java:187)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:268)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
        ... 20 more
    Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.EntityManagerSetupException
    Exception Description: Predeployment of PersistenceUnit [default] failed.
    Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException
    Exception Description: Entity class [class com.proxi.user.User] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
        at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:210)
        ... 26 more
    Caused by: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException
    Exception Description: Entity class [class com.proxi.user.User] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
        at org.eclipse.persistence.exceptions.ValidationException.noPrimaryKeyAnnotationsFound(ValidationException.java:1352)
        at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.validatePrimaryKey(EntityAccessor.java:1325)
        at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processMappingAccessors(EntityAccessor.java:1070)
        at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.process(EntityAccessor.java:603)
        at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage2(MetadataProject.java:1541)
        at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:485)
        at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:454)
        at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1081)
...
...
...

Here is my User.java class:

/**
 * 
 */
package com.proxi.user;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Table;

import org.springframework.data.annotation.Id;

/**
 * Represents an application user.
 */
@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    // /////// GETTERS AND SETTERS ///////////

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

And I have a root-context.xml file where I declare components:

<?xml version="1.0" encoding="UTF-8"?>
<beans 
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

    <!-- Root Context: defines shared resources visible to all other web components -->
    <bean id="userService" class="com.proxi.user.UserService" />    

    <!-- Starting with Spring 3.1, the persistence.xml XML file is no longer necessary. 
         The LocalContainerEntityManagerFactoryBean now supports a ‘packagesToScan’ property where the packages to scan 
         for @Entity classes can be specified. -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
       <property name="dataSource" ref="dataSource" />
       <property name="packagesToScan" value="com.proxi.user" />
       <property name="jpaVendorAdapter">
          <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
             <property name="showSql" value="true" />
             <property name="generateDdl" value="true" />
             <property name="databasePlatform" value="org.eclipse.persistence.platform.database.HSQLPlatform" />
          </bean>
       </property>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
       <property name="url" value="jdbc:hsqldb:file:\Users\nly31175\hsqldb;shutdown=true" />
       <property name="username" value="proxi" />
       <property name="password" value="" />
    </bean>

    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

</beans>
Foi útil?

Solução

You are importing the wrong @Id annotation. remove the spring one, add the javax.persistence one.

Replace

import org.springframework.data.annotation.Id;

with

import javax.persistence.Id;

Outras dicas

Although the accepted answer is correct in this case, there may be another reason for this error when using Glassfish / EclipseLink: EclipseLink <2.6.0 has a nasty bug causing classes with lambda expressions in it to be ignored. That may lead to confusing errors, like the one mentioned here, or other similar errors (for example, EclipseLink may tell you that a class with an @Entity annotation is not an entity).

Glassfish 4.1 includes EclipseLink 2.5.x, so this bug (and many many others) will bite you if using Glassfish. I was using this version instead of 4.1.1 due to another bug that made impossible to use validation in REST web services. Stay as far as possible from Glassfish if you want to keep your sanity.

Using Java-8, upgrade EclipseLink to at least 2.6.0 .

I had problems with adding any custom get/constructor apart from POJO.

Version Upgrade helped.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top