有没有办法在Maven项目中设置第二个persistence.xml文件,以便用于测试而不是用于部署的普通文件?
我尝试将一个persistence.xml放入src/test/resources/META-INF,它被复制到target/test-classes/META-INF中,但似乎是target/classes/META-INF(来自src/main的副本)尽管mvn -X test
以正确的顺序列出了类路径条目,但首选资源是首选的:
[DEBUG] Test Classpath : [DEBUG] /home/uqpbecke/dev/NetBeansProjects/UserManager/target/test-classes [DEBUG] /home/uqpbecke/dev/NetBeansProjects/UserManager/target/classes [DEBUG] /home/uqpbecke/.m2/repository/junit/junit/4.5/junit-4.5.jar ...
我希望能够针对简单的hsqldb配置运行测试,而无需更改JPA配置的部署版本,理想情况是在项目结账后直接进行,无需进行本地调整.
以下内容适用于Maven 2.1+(在此之前,测试和包之间没有可以绑定执行的阶段).
您可以使用maven-antrun-plugin在测试期间将persistence.xml替换为测试版本,然后在打包项目之前恢复正确的版本.
此示例假定生产版本为src/main/resources/META-INF/persistence.xml,测试版本为src/test/resources/META-INF/persistence.xml,因此它们将被复制到target/classes/META -INF和target/test-classes/META-INF分别.
将它封装成mojo会更优雅,但是因为你只是复制一个文件,所以看起来有点过分.
maven-antrun-plugin 1.3 copy-test-persistence process-test-resources run restore-persistence prepare-package run
在EE6/CDI/JPA项目中,src/test/resources/META-INF/persistence.xml
无需进一步配置即可完成测试.
在Spring中使用JPA时,以下工作在用于测试的应用程序上下文中:
在这里,/src/test/resources/META-INF/persistence.xml
(复制到target/test-classes
)将优先于/src/main/resources/META-INF/persistence.xml
(复制到target/classes
).
Unfortunately, the location of the persistence.xml
file also determines the so-called "persistence unit's root", which then determines which classes are scanned for @Entity
annotations. So, using /src/test/resources/META-INF/persistence.xml
would scan classes in target/test-classes
, not classes in target/classes
(where the classes that need to be tested would live).
Hence, for testing, one would need to explicitly add
entries to persistence.xml
, to avoid java.lang.IllegalArgumentException: Not an entity: class ...
. The need for
entries can be avoided by using a different file name, like persistence-TEST.xml
, and put that file in the very same folder as the regular persistence.xml
file. The Spring context from your test folder can then just refer to
, and Spring will find it for you in src/main
.
作为替代方案,可以persistence.xml
为实际应用程序和测试保持相同,并且仅定义一个src/main
.大多数配置(如驱动程序,方言和可选凭据)都可以在Spring上下文中完成.还hibernate.hbm2ddl.auto
可以在上下文中传递设置:
#{myConfig['db.ddl']}
#{myConfig['db.showSql']}
true
似乎多个persistence.xml文件是JPA的一般问题,只能通过类加载技巧来解决.
对我有用的解决方法是在一个persistence.xml文件中定义多个持久性单元,然后确保您的部署和测试代码使用不同的绑定(在Spring中,您可以在实体管理器工厂中设置"persistenceUnitName"属性).它会使用测试配置污染您的部署文件,但如果您不介意它可以正常工作.
为测试添加一个persistance.xml:/src/test/resources/META-INF/persistence.xml
正如@Arjan所说,这将改变持久性单元的根,实体类将在目标/测试类中进行扫描.要处理它,请将jar-file元素添加到此persistance.xml:
/src/test/resources/META-INF/persistence.xml
org.hibernate.jpa.HibernatePersistenceProvider ${project.basedir}/target/classes
然后,将测试资源的过滤添加到pom.xml:
... ... ...... src/test/resources true
这将起作用,因为jar文件可以定位到目录,而不仅仅是jar文件.
我尝试了ClassLoaderProxy方法但遇到的问题是,JPA带注释的类不会被hibernate作为持久化类处理.
所以决定不使用persistence.xml就试一试.优点是maven构建和Eclipse JUnit测试无需修改即可运行.
我有一个用于JUnit测试的persitent支持类.
public class PersistenceTestSupport { protected EntityManager em; protected EntityTransaction et; /** * Setup the the {@code EntityManager} and {@code EntityTransaction} for * local junit testing. */ public void setup() { Properties props = new Properties(); props.put("hibernate.hbm2ddl.auto", "create-drop"); props.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); props.put("hibernate.connection.url", "jdbc:mysql://localhost/db_name"); props.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver"); props.put("hibernate.connection.username", "user"); props.put("hibernate.connection.password", "****"); Ejb3Configuration cfg = new Ejb3Configuration(); em = cfg.addProperties(props) .addAnnotatedClass(Class1.class) .addAnnotatedClass(Class2.class) ... .addAnnotatedClass(Classn.class) .buildEntityManagerFactory() .createEntityManager(); et = em.getTransaction(); } }
我的测试类只是扩展PersistenceTestSupport并调用TestCase.setup()中的setup().
唯一的缺点是保持持久化的类,但对于JUnit测试,这对我来说是可以接受的.
我更喜欢使用不同的persistence.xml作为Rich Seller 帖子进行测试和制作的解决方案(谢谢!!).
但需要改变:
对于:
为了使persistence.xml.proper不嵌入.jar文件中