我知道使用以下指令:
Persistence.createEntityManagerFactory("persistence-unit-name");
JPA持久化机制会读取名为"persistence.xml"的文件,查找名为"persistence-unit-name"的持久化单元,并基于其构建EntityManagerFactory。
我的问题是,我如何强制JPA使用一个不同于"persistence.xml"的文件?例如,"persistence-test.xml"。
我知道使用以下指令:
Persistence.createEntityManagerFactory("persistence-unit-name");
JPA持久化机制会读取名为"persistence.xml"的文件,查找名为"persistence-unit-name"的持久化单元,并基于其构建EntityManagerFactory。
我的问题是,我如何强制JPA使用一个不同于"persistence.xml"的文件?例如,"persistence-test.xml"。
目前没有JPA标准的方法来实现这一点,尽管各个JPA提供者可能会提供一种方法。我建议使用标准的方法为主要和测试设置不同的类路径。
例如,如果您使用Maven,并且有两个META-INF/persistence.xml
文件,一个在src/main/resources
,另一个在src/test/resources
,测试将会拾取src/test/resources
中的文件,因为Maven会将测试类/资源放在主类/资源之前加载到类路径中。你可以轻松地配置Ant以类似的方式工作。
如果需要更高级的逻辑,请考虑使用Spring的JPA支持。它将使您能够处理高级情况,例如集成多个persistence.xml文件。
在 EclipseLink 中,您可以执行以下操作:
Properties pros = new Properties();
pros.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML,
"META-INF/persistence-alternative.xml");
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("pu-name", pros);
我认为你不能这样做。一个冗长的方法是:
persistence-test.xml
并呈现一个 Map<String, String>
属性。Persistence.createEntityManagerFactory(persistenceUnitName, Map properties)
。这样,它将从 properties
映射中读取而不是从 persistence.xml
中读取。我们希望拥有两个单独的文件。一个应该只被生产配置读取,另一个用于测试。这个想法是重命名或隐藏生产文件。
War解决方案
不要将放在中。而是将其放入中。这是文件应该放置的位置,在此处它不会被测试程序看到。
这个解决方案在Gradle环境下适用于我,但我希望它也能适用于其他环境。
Jar解决方案
将生产文件命名为。现在我们已经完成了测试配置。对于生产,我们必须进行一些处理。每个环境可能都有自己的方式,这就是我在Gradle中的做法:
tasks.withType(Jar) {
rename { fileName ->
fileName == "persistence-ee.xml" ? "persistence.xml" : fileName;
}
}
在我的应用程序中,persistence.xml
文件仅在部署时,即在jar / war包中才是必需的。而且这些都是唯一可见此文件的地方。如果没有双重的persistence
,我将无法启动我的数据库。主要原因是使用了jta-data-source
,另一个原因是使用了2个不同命名的持久化单元。
src\main\webapp\WEB-INF\classes\META-INF\
后,它对我起了魔法般的作用。非常非常非常感谢你! - Arthur Eirich:
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
Map<String, Object> properties = new Hashtable<>();
properties.put("javax.persistence.schema-generation.database.action",
"none");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); //you can change this if you have a different DB
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(adapter);
factory.setDataSource(this.springJpaDataSource());
factory.setPackagesToScan("package name");
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
factory.setValidationMode(ValidationMode.NONE);
factory.setJpaPropertyMap(properties);
return factory;
}
由于您没有使用persistence.xml,因此您应该创建一个bean,返回DataSource,您在上面设置数据源的方法中指定:
@Bean
public DataSource springJpaDataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:mysql://localhost/SpringJpa");
dataSource.setUsername("tomcatUser");
dataSource.setPassword("password1234");
return dataSource;
}
然后您需要在此配置文件上使用@EnableTransactionManagement
注释。现在当您放置该注释时,您必须创建最后一个bean:
@Bean
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject());
}
@Transactional
注释。EntityManager
(此存储库类应该在其上具有@Repository
注释)。