Inspired by this question: JPA using alternative "persistence.xml" I have created a folder structure as outlined below:
src/main/resources/META-INF/persistence.xml
src/test/resources/META-INF/persistence.xml
Both persistence-units
have the same name, since my goal is that tests should pick up the one in the test-folder
and otherwise the " normal
" one should be used. The answer to the question above claims that "Maven puts test classes / resources ahead of main classes / resources in the classpath" This however is not what I see. If the persistence-units
have the same name, it will always use the one in src/main/resources/
...
Any suggestions for how to solve this problem would be appreciated
So it seems that the reply to the original quoted question was wrong? So I ended up with another strategy as sketched below: I have a static class, which are always used to fetch the name for the Persistence Unit to use.
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;
}
}
Whenever I create an EntityManager I do it as sketched below. In this example it changes the name to use a "test persistence-unit"
@BeforeClass
public static void initClass(){
PU_Name.setPU_Name("puTest");
emf = Persistence.createEntityManagerFactory(PU.getPU_Name());
}
The real class is a bit more "advanced" since it also detects the presence of an OPENSHIFT environment variable and shifts to the Persistence Unit that uses the "production" database up there.
I have the same situation, with two persistence.xml in test and main resources. Always cannot detect the unique PU name in test classpath, even when I ensure hiberante-entitymanager
and the test file are on classpath.
At last I go for a solution: construct the entityManagerFactory programmatically, like here: create entity manager programmatically without persistence file .
So I did sth very similar:
@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;
}
}
But then, I found it still return null
. Why? Then I found in com.hibernate.ejb.HibernatePersistence
class, the provider should not be com.hibernate.jpa.HibernatePersistenceProvider
, but com.hibernate.ejb.HibernatePersistenc
. The class HibernatePersistenceProvider
is not even among my classpath.
In 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 {
So I went back to the first solution, and change provider name, and now it works.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.