实体扫描无法在JPA / hibernate / spring应用程序中工作

时间:2016-08-28 14:06:56

标签: java spring hibernate jpa wildfly-10

我的applicationContext.xml是:

<aop:aspectj-autoproxy/>

<context:component-scan base-package="com"/>
<context:annotation-config/>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<tx:jta-transaction-manager/>
<tx:annotation-driven/>

<jee:jndi-lookup id="corePU" jndi-name="java:/exampleDatasource" expected-type="javax.sql.DataSource"/>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:/META-INF/persistence.xml" />
    <property name="persistenceUnitName" value="corePU" />
    <property name="packagesToScan" value="com" />
</bean>

每个实体都有@Entitypersistence.xml以下属性设置为

<exclude-unlisted-classes>false</exclude-unlisted-classes>

Hibernate version : 5.1.0.Final
Spring version : 4.1.3.RELEASE
JPA 2.0
WildFly 10

applicationContext.xml中,我已经定义了一个entityManagerFactory bean,如下所示&#34;

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:/META-INF/persistence.xml" />
    <property name="persistenceUnitName" value="corePU" />
    <property name="packagesToScan" value="com" />
</bean>

persistence.xml如下:

<persistence-unit name="corePU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>java:/exampleDatasource</jta-data-source>
    <!--<class>com.entity.Address</class>-->

    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <!--<shared-cache-mode>NONE</shared-cache-mode>-->
    <properties>
        <property name="hibernate.hbm2ddl.auto" value="validate" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        <property name="hibernate.show_sql" value="false"/>
        <property name="hibernate.format_sql" value="false"/>
        <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"/>
        <property name="org.hibernate.envers.audit_table_prefix" value="z_"/>
        <property name="hibernate.cache.use_second_level_cache" value="false" />
        <property name="hibernate.generate_statistics" value="false"/>
        <property name="hibernate.cache.use_query_cache" value="false"/>
        <property name="hibernate.archive.autodetection" value="class, hbm" />

    </properties>
</persistence-unit>

以下是我得到的错误:

21:15:47,463 ERROR [stderr] (default task-4) java.lang.IllegalArgumentException: Unknown entity: com.entity.Address
21:15:47,463 ERROR [stderr] (default task-4)    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1149)
21:15:47,464 ERROR [stderr] (default task-4)    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
21:15:47,464 ERROR [stderr] (default task-4)    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
21:15:47,464 ERROR [stderr] (default task-4)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
21:15:47,464 ERROR [stderr] (default task-4)    at java.lang.reflect.Method.invoke(Method.java:498)
21:15:47,464 ERROR [stderr] (default task-4)    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347)
21:15:47,464 ERROR [stderr] (default task-4)    at com.sun.proxy.$Proxy93.persist(Unknown Source)
21:15:47,464 ERROR [stderr] (default task-4)    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
21:15:47,464 ERROR [stderr] (default task-4)    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
21:15:47,464 ERROR [stderr] (default task-4)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
21:15:47,464 ERROR [stderr] (default task-4)    at java.lang.reflect.Method.invoke(Method.java:498)
21:15:47,465 ERROR [stderr] (default task-4)    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
21:15:47,465 ERROR [stderr] (default task-4)    at com.sun.proxy.$Proxy50.persist(Unknown Source)
21:15:47,465 ERROR [stderr] (default task-4)    at com.manager.manager.getAddress(manager.java:37)
21:15:47,465 ERROR [stderr] (default task-4)    at com.manager.manager$$FastClassBySpringCGLIB$$e766fff.invoke(<generated>)
21:15:47,465 ERROR [stderr] (default task-4)    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

如何在persistence.xml中使用class标记明确指定每个实体的情况下如何使用我的实体?

2 个答案:

答案 0 :(得分:7)

JPA和Spring是两回事。

一般来说,Spring的<context:component-scan base-package="..."/> 与JPA 无关。它指的是Spring组件,垃圾箱等。但是当然,Spring使用JPA并且有两种可能的配置:

  • 将Spring配置为读取persistence.xml 并完全依赖它;
  • 不要使用persistence.xml 并仅使用Spring配置 - 另一种配置类型,您可以使用LocalContainerEntityManagerFactoryBean属性packagesToScan。请参阅此帖子,例如:https://stackoverflow.com/a/16088340/2816631

检查Spring javadoc对packagesToScan

的说法
  

设置是否对实体类使用基于Spring的扫描   classpath而不是使用JPA标准的jar文件扫描   其中包含persistence.xml标记。如果是基于Spring的扫描,没有   persistence.xml是必要的;你需要做的就是指定基数   包在这里搜索。

如果您想使用persistence.xml ,您有几个选择:

  • 编写每个实体类 - JPA不支持自动扫描(好吧,差不多,请参阅下一个选项);
  • 不要编写每个实体类,而是将您的实体放在一个jar中,并将jar-file属性设置为指向它 - JPA仅支持这种自动扫描;
  • 如果您不介意不符合JPA规范(即使用JPA本身没有的特定提供程序功能),您可以使用 Hibernate自动扫描功能:

休眠自动扫描功能:

<persistence-unit name="unitName" transaction-type="RESOURCE_LOCAL">
  <!-- This is required to be spec compliant, Hibernate however supports
       auto-detection even in JSE.
  <class>com.entity.User</class>
  <class>com.entity.Address</class>
  ...
   -->

  <properties>
    <!-- Scan for annotated classes and Hibernate mapping XML files -->
    <property name="hibernate.archive.autodetection" value="class, hbm"/>
    ...
  </properties>
</persistence-unit>

答案 1 :(得分:3)

您应该在packagesToScan / entityManager配置中设置sessionFactory属性。

例如:

packagesToScan="com.manager"

或者,如果您使用的是Spring Boot,则可以使用@EntityScan注释:

rawurlencode

Spring Boot 1.4+