实体扫描在 JPA/hibernate/spring 应用程序中不起作用
Entity scanning not working in JPA/hibernate/spring application
我的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>
每个实体都有 @Entity
并且在 persistence.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,如下所示
<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
标签明确指定每个实体,我该如何使用我的实体?
您应该在 entityManager
/ sessionFactory
配置中设置 packagesToScan
属性。
例如:
packagesToScan="com.manager"
或者,如果您使用的是 Spring 引导,则可以使用 @EntityScan
注释:
JPA 和 Spring 是两个不同的东西。
Spring的<context:component-scan base-package="..."/>
一般与JPA无关。它指的是 Spring 组件、容器等。但在幕后,当然,Spring 使用 JPA,并且有两种可能的配置:
- 配置Spring到读取persistence.xml,完全依赖它;
- 不要使用 persistence.xml 并仅使用 Spring 配置 - 另一种类型的配置,您可以在其中使用
LocalContainerEntityManagerFactoryBean
属性packagesToScan
。请参阅此 post,例如:.
查看 Spring javadoc 对 packagesToScan
:
的描述
Set whether to use Spring-based scanning for entity classes in the
classpath instead of using JPA's standard scanning of jar files with
persistence.xml markers in them. In case of Spring-based scanning, no
persistence.xml is necessary; all you need to do is to specify base
packages to search here.
如果你想使用persistence.xml,你有几个选择:
- 写入每个实体class - JPA 不支持自动扫描(嗯,差不多,看下一个选项);
- 不要编写每个实体 class,而是将您的实体放在一个 jar 中并设置
jar-file
属性 指向它 - JPA 仅支持这种自动 -扫描;
- 如果您不介意不符合 JPA 规范(即使用 JPA 本身没有的特定提供程序功能),您可以使用 Hibernate 自动扫描 功能:
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>
我的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>
每个实体都有 @Entity
并且在 persistence.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,如下所示
<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
标签明确指定每个实体,我该如何使用我的实体?
您应该在 entityManager
/ sessionFactory
配置中设置 packagesToScan
属性。
例如:
packagesToScan="com.manager"
或者,如果您使用的是 Spring 引导,则可以使用 @EntityScan
注释:
JPA 和 Spring 是两个不同的东西。
Spring的<context:component-scan base-package="..."/>
一般与JPA无关。它指的是 Spring 组件、容器等。但在幕后,当然,Spring 使用 JPA,并且有两种可能的配置:
- 配置Spring到读取persistence.xml,完全依赖它;
- 不要使用 persistence.xml 并仅使用 Spring 配置 - 另一种类型的配置,您可以在其中使用
LocalContainerEntityManagerFactoryBean
属性packagesToScan
。请参阅此 post,例如:.
查看 Spring javadoc 对 packagesToScan
:
Set whether to use Spring-based scanning for entity classes in the classpath instead of using JPA's standard scanning of jar files with persistence.xml markers in them. In case of Spring-based scanning, no persistence.xml is necessary; all you need to do is to specify base packages to search here.
如果你想使用persistence.xml,你有几个选择:
- 写入每个实体class - JPA 不支持自动扫描(嗯,差不多,看下一个选项);
- 不要编写每个实体 class,而是将您的实体放在一个 jar 中并设置
jar-file
属性 指向它 - JPA 仅支持这种自动 -扫描; - 如果您不介意不符合 JPA 规范(即使用 JPA 本身没有的特定提供程序功能),您可以使用 Hibernate 自动扫描 功能:
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>