EclipseLink错误:实体类没有指定主键。它应该定义@ Id,@ EmbeddedId或@IdClass

时间:2012-04-25 16:02:28

标签: java spring jpa spring-data spring-data-jpa

我正在尝试让EclipseLink与Spring(MVC和spring-data)版本3.1.1一起使用,我从一开始就遇到了问题。启动Tomcat(v7.0)时会出现以下错误。我已经搜索了这个错误,但提出的却很少,我不确定下一步该去哪里。在使用具有Entity类的接口时会出现一些关于此问题的讨论,但正如您所看到的那样,User.java类没有任何扩展。

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

这是我的User.java类:

/**
 * 
 */
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;
    }
}

我有一个root-context.xml文件,我在其中声明组件:

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

3 个答案:

答案 0 :(得分:9)

您正在导入错误的@Id注释。删除spring one,添加javax.persistence。

替换

import org.springframework.data.annotation.Id;

import javax.persistence.Id;

答案 1 :(得分:1)

虽然在这种情况下接受的答案是正确的,但在使用Glassfish / EclipseLink时可能还有另一个原因导致此错误:EclipseLink&lt; 2.6.0有一个nasty bug导致其中包含lambda表达式的类被忽略。这可能会导致混淆错误(如此处提到的错误)或其他类似错误(例如,EclipseLink可能会告诉您具有@Entity注释的类不是实体)。

Glassfish 4.1包含EclipseLink 2.5.x,因此如果使用Glassfish,这个错误(以及许多其他错误)会让你感到厌烦。由于另一个无法在REST Web服务中使用验证的错误,我使用的是此版本而不是4.1.1。如果你想保持理智,请尽量远离Glassfish。

答案 2 :(得分:0)

使用Java-8,将EclipseLink升级到至少2.6.0。

我在添加除POJO之外的任何自定义get /构造函数时遇到了问题。

版本升级帮助。