有一个单独的 persistence.xml 文件用于测试
Having a separate persistence.xml file for testing
受到这个问题的启发:JPA using alternative "persistence.xml"我创建了一个如下所示的文件夹结构:
src/main/resources/META-INF/persistence.xml
src/test/resources/META-INF/persistence.xml
两者 persistence-units
具有相同的名称,因为我的目标是测试应该选择 test-folder
中的那个,否则应该使用“normal
”。
上述问题的答案声称 "Maven puts test classes / resources ahead of main classes / resources in the classpath"
然而,这不是我所看到的。如果 persistence-units
具有相同的名称,它将始终使用 src/main/resources/
...
中的那个
如有任何解决此问题的建议,我们将不胜感激
原来引用的问题好像回复错了?所以我最终采用了另一种策略,如下所示:
我有一个静态 class,它总是用于获取要使用的持久性单元的名称。
public class PU_Name
{
private static String puName = "pu_delopment";
public static String getPU_Name(){
return puName;
}
public static void setPU_Name(String name){
puName = name;
}
}
每当我创建一个 EntityManager 时,我都会按照下面的草图进行操作。在此示例中,它更改名称以使用 "test persistence-unit"
@BeforeClass
public static void initClass(){
PU_Name.setPU_Name("puTest");
emf = Persistence.createEntityManagerFactory(PU.getPU_Name());
}
真正的 class 多一点 "advanced" 因为它还检测到 OPENSHIFT 环境变量的存在并转移到使用 "production" 数据库的持久性单元。
我也有同样的情况,在测试和主要资源中有两个persistence.xml。始终无法在测试 classpath 中检测到唯一的 PU 名称,即使我确保 hiberante-entitymanager
并且测试文件位于 classpath.
最后我寻求解决方案:以编程方式构造 entityManagerFactory,如下所示:create entity manager programmatically without persistence file.
所以我做了非常相似的事情:
@BeforeClass
public static void prepare() {
Map<String, Object> configOverrides = new HashMap<>();
configOverrides.put("hibernate.connection.driver_class", "org.h2.Driver");
configOverrides.put("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
configOverrides.put("hibernate.connection.username", "sa");
configOverrides.put("hibernate.connection.password", "sa");
configOverrides.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
configOverrides.put("hibernate.show_sql", "true");
configOverrides.put("hibernate.hbm2ddl.auto", "validate");
//factory = new HibernatePersistence().createContainerEntityManagerFactory(
// new CustomPersistenceUnitInfo(), configOverrides
//);
factory = Persistence.createEntityManagerFactory("test");
assertNotNull(factory);
}
...
private static class CustomPersistenceUnitInfo implements PersistenceUnitInfo {
@Override
public String getPersistenceUnitName() {
return "test";
}
@Override
public String getPersistenceProviderClassName() {
return "org.hibernate.jpa.HibernatePersistenceProvider";
// <------------note here: this is wrong!
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
@Override
public DataSource getJtaDataSource() {
return null;
}
@Override
public DataSource getNonJtaDataSource() {
return null;
}
@Override
public List<String> getMappingFileNames() {
return Collections.emptyList();
}
@Override
public List<URL> getJarFileUrls() {
try {
return Collections.list(this.getClass()
.getClassLoader()
.getResources(""));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public URL getPersistenceUnitRootUrl() {
return null;
}
@Override
public List<String> getManagedClassNames() {
return Arrays.asList(
"com.app.Entity1",
"com.app.Entity2"
);
}
@Override
public boolean excludeUnlistedClasses() {
return true;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return null;
}
@Override
public ValidationMode getValidationMode() {
return null;
}
@Override
public Properties getProperties() {
return null;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return null;
}
@Override
public ClassLoader getClassLoader() {
return null;
}
@Override
public void addTransformer(final ClassTransformer classTransformer) {
}
@Override
public ClassLoader getNewTempClassLoader() {
return null;
}
}
但是后来,我发现还是returnnull
。为什么?然后我在com.hibernate.ejb.HibernatePersistence
class中发现,provider不应该是com.hibernate.jpa.HibernatePersistenceProvider
,而是com.hibernate.ejb.HibernatePersistenc
。 class HibernatePersistenceProvider
甚至不在我的 class 路径中。
在Ejb3Configuration.class
中:
integration = integration != null ? Collections.unmodifiableMap(integration) : CollectionHelper.EMPTY_MAP;
String provider = (String)integration.get("javax.persistence.provider");
if (provider == null) {
provider = info.getPersistenceProviderClassName();
}
if (provider != null && !provider.trim().startsWith(IMPLEMENTATION_NAME)) { // private static final String IMPLEMENTATION_NAME = HibernatePersistence.class.getName(); which, is, "com.hibernate.ejb.HibernatePersistence"
LOG.requiredDifferentProvider(provider);
return null;
} else {
所以我回到第一个解决方案,更改提供商名称,现在可以了。
受到这个问题的启发:JPA using alternative "persistence.xml"我创建了一个如下所示的文件夹结构:
src/main/resources/META-INF/persistence.xml
src/test/resources/META-INF/persistence.xml
两者 persistence-units
具有相同的名称,因为我的目标是测试应该选择 test-folder
中的那个,否则应该使用“normal
”。
上述问题的答案声称 "Maven puts test classes / resources ahead of main classes / resources in the classpath"
然而,这不是我所看到的。如果 persistence-units
具有相同的名称,它将始终使用 src/main/resources/
...
如有任何解决此问题的建议,我们将不胜感激
原来引用的问题好像回复错了?所以我最终采用了另一种策略,如下所示: 我有一个静态 class,它总是用于获取要使用的持久性单元的名称。
public class PU_Name
{
private static String puName = "pu_delopment";
public static String getPU_Name(){
return puName;
}
public static void setPU_Name(String name){
puName = name;
}
}
每当我创建一个 EntityManager 时,我都会按照下面的草图进行操作。在此示例中,它更改名称以使用 "test persistence-unit"
@BeforeClass
public static void initClass(){
PU_Name.setPU_Name("puTest");
emf = Persistence.createEntityManagerFactory(PU.getPU_Name());
}
真正的 class 多一点 "advanced" 因为它还检测到 OPENSHIFT 环境变量的存在并转移到使用 "production" 数据库的持久性单元。
我也有同样的情况,在测试和主要资源中有两个persistence.xml。始终无法在测试 classpath 中检测到唯一的 PU 名称,即使我确保 hiberante-entitymanager
并且测试文件位于 classpath.
最后我寻求解决方案:以编程方式构造 entityManagerFactory,如下所示:create entity manager programmatically without persistence file.
所以我做了非常相似的事情:
@BeforeClass
public static void prepare() {
Map<String, Object> configOverrides = new HashMap<>();
configOverrides.put("hibernate.connection.driver_class", "org.h2.Driver");
configOverrides.put("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
configOverrides.put("hibernate.connection.username", "sa");
configOverrides.put("hibernate.connection.password", "sa");
configOverrides.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
configOverrides.put("hibernate.show_sql", "true");
configOverrides.put("hibernate.hbm2ddl.auto", "validate");
//factory = new HibernatePersistence().createContainerEntityManagerFactory(
// new CustomPersistenceUnitInfo(), configOverrides
//);
factory = Persistence.createEntityManagerFactory("test");
assertNotNull(factory);
}
...
private static class CustomPersistenceUnitInfo implements PersistenceUnitInfo {
@Override
public String getPersistenceUnitName() {
return "test";
}
@Override
public String getPersistenceProviderClassName() {
return "org.hibernate.jpa.HibernatePersistenceProvider";
// <------------note here: this is wrong!
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
@Override
public DataSource getJtaDataSource() {
return null;
}
@Override
public DataSource getNonJtaDataSource() {
return null;
}
@Override
public List<String> getMappingFileNames() {
return Collections.emptyList();
}
@Override
public List<URL> getJarFileUrls() {
try {
return Collections.list(this.getClass()
.getClassLoader()
.getResources(""));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public URL getPersistenceUnitRootUrl() {
return null;
}
@Override
public List<String> getManagedClassNames() {
return Arrays.asList(
"com.app.Entity1",
"com.app.Entity2"
);
}
@Override
public boolean excludeUnlistedClasses() {
return true;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return null;
}
@Override
public ValidationMode getValidationMode() {
return null;
}
@Override
public Properties getProperties() {
return null;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return null;
}
@Override
public ClassLoader getClassLoader() {
return null;
}
@Override
public void addTransformer(final ClassTransformer classTransformer) {
}
@Override
public ClassLoader getNewTempClassLoader() {
return null;
}
}
但是后来,我发现还是returnnull
。为什么?然后我在com.hibernate.ejb.HibernatePersistence
class中发现,provider不应该是com.hibernate.jpa.HibernatePersistenceProvider
,而是com.hibernate.ejb.HibernatePersistenc
。 class HibernatePersistenceProvider
甚至不在我的 class 路径中。
在Ejb3Configuration.class
中:
integration = integration != null ? Collections.unmodifiableMap(integration) : CollectionHelper.EMPTY_MAP;
String provider = (String)integration.get("javax.persistence.provider");
if (provider == null) {
provider = info.getPersistenceProviderClassName();
}
if (provider != null && !provider.trim().startsWith(IMPLEMENTATION_NAME)) { // private static final String IMPLEMENTATION_NAME = HibernatePersistence.class.getName(); which, is, "com.hibernate.ejb.HibernatePersistence"
LOG.requiredDifferentProvider(provider);
return null;
} else {
所以我回到第一个解决方案,更改提供商名称,现在可以了。