Hi, I am using persistence.xml in which i am explicitly specifying the jar, is there a way I can move out the persistence.xml from my project, since i am uploading my project jar onto a server and it is difficult to replace the jar at runtime, or can we give the jar via program while creating entityManagerFactory
You can build an EntityManagerFactory
manually as well through e.g. PersistenceProviderResolverHolder.getPersistenceProviderResolver().getPersistenceProviders()
and createContainerEntityManagerFactory()
, where you can pass a custom PersistenceUnitInfo
essentially representing that persistence.xml.
Hi thanks for the reply,
can you give me a sample code that works because I tried but it is kinda not working
below is the implementation that i tried
File jarFile = new File("jar-path");
URL jarUrl = jarFile.toURI().toURL();
logger.info("Loading JAR URL: " + jarUrl);
JarPersistenceUnitInfo persistenceUnitInfo = new JarPersistenceUnitInfo("dynamicPU", jarUrl, properties);
EntityManagerFactory emf = new HibernatePersistenceProvider()
.createContainerEntityManagerFactory(persistenceUnitInfo, properties);
SessionFactory sessionFactory = emf.unwrap(SessionFactory.class);
and this is the custom persistentunitinfo
package com.bancbox.v4.config;
import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.ValidationMode;
import jakarta.persistence.spi.ClassTransformer;
import jakarta.persistence.spi.PersistenceUnitInfo;
import jakarta.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import java.net.URL;
import java.util.*;
public class JarPersistenceUnitInfo implements PersistenceUnitInfo {
private final String persistenceUnitName;
private final URL jarUrl;
private final Properties properties;
public JarPersistenceUnitInfo(String persistenceUnitName, URL jarUrl, Properties properties) {
this.persistenceUnitName = persistenceUnitName;
this.jarUrl = jarUrl;
this.properties = properties;
}
@Override
public String getPersistenceUnitName() {
return persistenceUnitName;
}
@Override
public String getPersistenceProviderClassName() {
return "org.hibernate.jpa.HibernatePersistenceProvider";
}
@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() {
return Collections.singletonList(jarUrl);
}
@Override
public URL getPersistenceUnitRootUrl() {
return jarUrl;
}
@Override
public List<String> getManagedClassNames() {
return Collections.emptyList(); // Hibernate will scan the JAR
}
@Override
public boolean excludeUnlistedClasses() {
return true;
}
@Override
public Properties getProperties() {
return properties;
}
@Override
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
@Override
public ClassLoader getNewTempClassLoader() {
return getClassLoader();
}
@Override
public SharedCacheMode getSharedCacheMode() {
return SharedCacheMode.UNSPECIFIED; // ✅ Default safe value
}
@Override
public ValidationMode getValidationMode() {
return ValidationMode.AUTO; // ✅ Ensures validation runs correctly
}
@Override
public String getPersistenceXMLSchemaVersion() {
return "2.1"; // ✅ Default to latest JPA version
}
@Override
public void addTransformer(ClassTransformer transformer) {
// No implementation needed unless you require bytecode transformation
}
}
and this is the error that i am facing
2025-02-19 17:31:10 [fibernate-API(1)] ERROR - exception -> java.lang.IllegalStateException: ArchiveDescriptor reused; can URLs be processed multiple times?
2025-02-19 17:31:10 [fibernate-API(1)] ERROR - exception -> java.lang.IllegalStateException: ArchiveDescriptor reused; can URLs be processed multiple times?
can you tell me what I am doing wrong here?
It looks like the JAR might be scanned multiple times, which happens because you’re returning the JAR URL also in getPersistenceUnitRootUrl()
. Return null
in getPersistenceUnitRootUrl()
to make this work.
If you’re willing to work with Hibernate APIs though, why not use the Configuration
API? That should be way easier if you want programmatic configuration.
Well ArchiveDescriptor error is not coming but still when i am trying to persists any entity, I am getting unable to locate persister…
and if I will be using configuration api then how can I send the jar path for entities then?
Don’t get me wrong, but you will have to read into the code a bit and read java docs. The Configuration
class has a addJar
method which is pretty self-explanatory, but also has good javadoc.
ok Thanks for the feedback, I will look into it again