Spring Data JPA:java.lang.IllegalArgumentException: 不是一个实体

13

我创建了一个Spring Data JPA示例项目,使用eclips进行开发。这里有两个项目,一个是仅包含实体类注解的领域对象项目。另一个项目是实际的Spring Data JPA项目,它依赖于项目一。实际上,它通过Maven依赖获取领域项目实体类。

项目1:hrm-domain

实体类:

package com.hrm.ws.data.domain;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;



@Entity(name = "Employee")
@Table(name = "employee")
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee {

    protected long id;

    protected String firstName;

    protected String lastName;

    /**
     * Gets the value of the id property.
     * 
     */
    @Id
    @Column(name = "id", scale = 0)
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }

项目2: hrm-ws-service

persistance-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:jpa="http://www.springframework.org/schema/data/jpa"

       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/data/jpa
                           http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">


        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="${jdbc.driverClassName}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </bean>

        <jpa:repositories base-package="com.hrm.ws.data.repository" />


        <bean id="employeeDao" class="com.hrm.ws.data.repository.EmployeeRepositoryImpl"/>      


        <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">

              <property name="entityManagerFactory" ref="entityManagerFactory" />
              <property name="jpaDialect">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
              </property>

        </bean>

        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

              <property name="dataSource" ref="dataSource" />

              <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                  <property name="generateDdl" value="${jdbc.generateDdl}" />
                  <property name="showSql" value="${jdbc.showSql}"/>
                </bean>
              </property>
              <property name="persistenceUnitName" value="jpa.sample" />

        </bean>

</beans>

我的packages设置如下:

src/main/java - 包含Spring的repository

src/main/resources - 包含应用程序上下文

src/test/java - 包含单元测试

以及项目1(hrm-domain)的依赖关系。

我的问题是:当我运行此项目时,出现以下错误:

... 38 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Not an entity: class com.hrm.ws.data.domain.Employee
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1429)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:844)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:786)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
    ... 40 more


**Caused by: java.lang.IllegalArgumentException: Not an entity: class** com.hrm.ws.data.domain.Employee
    at org.hibernate.ejb.metamodel.MetamodelImpl.entity(MetamodelImpl.java:160)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:52)
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:61)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:145)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:83)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:66)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:146)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:120)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:39)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
    ... 48 more

我对这个问题感到困惑,因为当我把领域对象(Employee.java)放在我的Spring项目中而不是单独的jar包中时,它可以正常工作。只有当它作为单独的jar包时才会出现这个问题。如果有人对这种情况有经验,请给我帮助。


从示例中看不出来,但是Employee有构造函数吗? - Dewfy
2
请提供“persistence.xml”的内容。在bean entityManagerFactory中,持久化单元名称“jpa.sample”是否正确? - Elias Dorneles
我也遇到了同样的问题,你能找出问题所在吗?我的项目在一个单独的Maven JPA-Facet项目中有注释类(该项目被Maven Spring基础项目引用)。 - higuaro
请注意,上游项目中声明的实体需要在下游项目的persistence.xml文件的persistence-unit中列出,以便下游项目可以使用它。 - 8bitjunkie
可能与你的问题无关,但如果你升级了Java到Java 8,那么Spring3将无法工作。你必须升级到Spring 4,请查看此帖子中给出的步骤来解决这个问题:http://stackoverflow.com/a/30204461/526438 - Sadanand
3个回答

7
我也遇到了同样的问题。我的问题是在entityManagerFactory bean中没有提供packagesToScan属性,因此Spring无法加载实体。请检查您的spring配置xml文件中emf bean的声明。以下是EMF声明,我希望它能够帮助您解决错误:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="packagesToScan" value="com.hrm.ws.data.domain" />
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
    </property>
</bean>

我没有Spring XML配置文件,因为我完全使用注释进行bean配置。在Hibernate 5.2.2中是否有一种使用注释的方法来实现这一点? - nzhenry

1
您没有扫描 com.hrm.ws.data.domain 包中使用 @Entity 注释的 bean,因此 Spring 容器不知道您的实体,从而产生异常。请将以下行添加到 persistance-context.xml 配置文件中:
<context:annotation-config />
<context:component-scan base-package="com.hrm.ws.data.domain" />

您还需要更改根XML元素,以便上下文元素得到识别:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/data/jpa
                           http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.0.xsd">

如果你还没有这样做,将spring-context依赖项添加到你的pom文件中。


我也有同样的问题,如果实体注释类在另一个Maven项目中(当然是从基于Spring的项目引用的),该怎么办?我按照你说的做了,但我仍然像@Hasitha一样收到相同的错误...还可能是什么问题? - higuaro
具有实体的Maven项目应该定义自己的上下文并扫描已注释实体存在的包。另一个项目(使用实体的消费者,我假设是主要项目?)应通过导入Spring XML文件引用其他上下文。以下是如何执行此操作的示例:http://www.mkyong.com/spring3/spring-3-javaconfig-import-example/。话虽如此,没有看到代码很难确定实际发生了什么。 - threejeez

0

使用以下选项之一:

  1. 在spring.xml文件中使用context:component-scan base-package="您的基础包名称"

  2. 在entityManagerFactory上设置packagesToScan属性

  3. 使用persistence.xml并在其中列出所有实体。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接