问题描述: java
JPA会自动读取同一jar包下,标注@Entity的实体类。可是若是所使用的实体和persistent.xml不在同一jar包时,会读取不到,而致使IllegalArgumentException: Not an managed type: class foo.bar spring
解决方案1: 模块化
在persistence.xml明确指定须要被JPA管理的实体。以下: 测试
<?xml version="1.0" encoding="UTF-8"?> <persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit transaction-type="RESOURCE_LOCAL" name="persistenceUnit"> <class>foo.bar1</class> <class>foo.bar2</class> </persistence-unit> </persistence>
这种方法的缺点很明显。既然是persistence.xml和entity类,那么项目就确定是分红了多个模块,或者是运行测试用例。可是要想找到实体,仍然须要集中修改persistence.xml。这样并非真正的模块化,还需集中处理各个业务对象。 spa
解决方案2: code
使用Spring管理JPA。在3.0以上的版本中(具体忘了是3.0.几开始支持的了),用org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,配置packagesToScan属性,Spring会自动扫描并加载该包及其子包下全部的@Entity。 orm
之前一直知道这个方法,可是每次试都不起做用,怀疑是Spring的一个BUG。今天静下心来读了一下这块的源码,发现若是要让这个属性起做用,就必定不能配置persistenceXmlLocation属性。persistenceXmlLocation用来指定persistence.xml的位置,若是指定这个属性,Spring就不会彻底托管JPA。如今,删除这个属性,就意味着能够把persistence.xml文件也一并删掉了。 xml
配置示例: 对象
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="packagesToScan" value="${base.package.name}" /> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:showSql="true" p:generateDdl="true" p:databasePlatform="${database.platform}" /> </property> </bean>