我有同样的情况,在测试和主要资源中有两个persistence.xml。始终无法检测到测试类路径中的唯一 PU 名称,即使我确保 hiberante-entitymanager 并且测试文件位于类路径中。
最后我找到了一个解决方案:以编程方式构造 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;
}
}
然后,我发现它仍然返回null。为什么?然后我发现在com.hibernate.ejb.HibernatePersistence类中,provider应该不是com.hibernate.jpa.HibernatePersistenceProvider,而是com.hibernate.ejb.HibernatePersistenc。 HibernatePersistenceProvider 类甚至不在我的类路径中。
在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 {
所以我回到了第一个解决方案,并更改了提供商名称,现在它可以工作了。