Our project, efluid, contains several modules (jar) which contain entity.
“Efluid” depends on the “ecore” jar and the “archi” jar.
In the hibernate configuration file, persistence xml, it is possible either to define the classes by hand and to list the jars.
I do not wish to add them by hand because they are numerous and wish to go through a discovery.
But the problem is that these jars are described in the pom.xml file stored in a mavent repository and not in a / lib subdirectory.
Suddenly, I do not know their name, the version for example that is in the name, and their location.
So I can’t reference these jars.
Any idea how to do it? ^^
Otherwise I saw the mechanism which allows to scan all the META-INf / persistence.xml of each jar, but this creates a persistence unit isolated from each other.
In summary, how to manage a persistence unit distributed in several jars via maven.
I would suggest to add orm.xml files to the JARs that list all entities the JAR contains and refer to that orm.xml files then in the main persistence.xml.
I understand that you would like to have this, but this is not directly possible. With Spring you can specify packages to scan with @EntityScan, but there is a class path scanning cost to this. At least with Hibernate directly, listing the JARs or classes individually is your only option.
If you want to use the JAR approach, you will have to know the names, that’s true. You could use maven resource filtering which allows you to replace properties during the resource copying with some value i.e. the version of an artifact. You could also adapt how the artifacts are packaged by specifying the finalName setting in the Maven build, such that the names are stable and independent of the version. There are many possibilities to solve this, but I would recommend you use the orm.xml approach as doesn’t require you to fiddle with the build and also doesn’t require scanning the class path.
The exploitation of the ORM.XML will be my final solution to improve performance and avoid the CLASSPATH scan.
I implemented a solution that allows you to exploit the indicating the name of the persistent-unit and overloading StandardArchiveDescriptorFactory#adjustjarfileentryurl.
I convert the name of the persistent unit into URL that points to the JAR that contains the persistent.xml.
What do you think ?
public class EfluidScanner extends AbstractScannerImpl {
public EfluidScanner() {
this(EfluidArchiveDescriptorFactory.INSTANCE);
}
public EfluidScanner(ArchiveDescriptorFactory value) {
super(value);
}
}
public class EfluidArchiveDescriptorFactory extends StandardArchiveDescriptorFactory {
public static final EfluidArchiveDescriptorFactory INSTANCE = new EfluidArchiveDescriptorFactory();
private static List<ParsedPersistenceXmlDescriptor> parsedPersistenceXmlDescriptors;
@Override
public URL adjustJarFileEntryUrl(URL url, URL rootUrl) {
if (url.getPath().contains(".")) {
return super.adjustJarFileEntryUrl(url, rootUrl);
} else {
return rechercherURLPersistenceUnitName(url);
}
}
private URL rechercherURLPersistenceUnitName(URL url) {
String module = url.getPath();
ParsedPersistenceXmlDescriptor parsedPersistenceXmlDescriptor =
getPersistencesXML().stream().filter(persistenceXml -> module.equals(persistenceXml.getName())).findFirst()
.orElseThrow(() -> new GenericException("Aucun persistence unit de nom " + module + " trouvé dans les fichiers META-INF/persistence.xml des jar référencés dans le classpath."));
return parsedPersistenceXmlDescriptor.getPersistenceUnitRootUrl();
}
private List<ParsedPersistenceXmlDescriptor> getPersistencesXML() {
if (parsedPersistenceXmlDescriptors == null) {
parsedPersistenceXmlDescriptors = PersistenceXmlParser.locatePersistenceUnits(emptyMap());
}
return parsedPersistenceXmlDescriptors;
}
}