I was able to get Hibernate 5.0 Osgi Bundles work with Equinox 4.5.0 in Unmanaged JPA mode. There is one problem though, when I use a custom UserType (for example TestTypeMapType which implements EnhancedUserType) in one of my entities I get the following exception:
org.hibernate.MappingException: Could not determine type for: com.xxx.yyy.TestTypeMapType, at table: TestTable, for columns: [org.hibernate.mapping.Column(testType)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:390)
When I check SimpleValue.java from Hibernate sources I see that it is using org.hibernate.internal.util.Reflecthelper to create the type info with the below line of code
ReflectHelper.classForName(typeName);
and ReflectHelper is using the below lines to create the type info
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader != null) {
return classLoader.loadClass(typeName);
}
}
catch(Throwable ignore){}
return Class.forName(typeName);
Both classLoader.loadClass and Class.forName throws the below exception
java.lang.ClassNotFoundException: com.xxx.yyy.TestTypeMapType cannot be found by org.hibernate.core_5.0.2.Final
But if I execute ReflectHelper.classForName contents directly from the bundle which creates the EntityManagerFactory, I can successfully create the type info of custom UserType. Specifically for the below example line-A and line-B works but line-C throws exception.
try {
Class<?> typeClass = null;
// A
typeClass = Thread.currentThread().getContextClassLoader().loadClass("com.xxx.yyy.TestTypeMapType");
// B
typeClass = Class.forName("com.xxx.yyy.TestTypeMapType");
// C
typeClass = ReflectHelper.classForName("com.xxx.yyy.TestTypeMapType");
}
catch(Exception e){}
What can I do, so that my custom UserType can be discovered by hibernate in the osgi environment?
PS: I have no problems with other Entity classes, dialect, jdbc driver etc. and also ReflectHelper.classForName is deprecated and it is advised to use either ClassLoaderService or ClassLoaderAccess. Can it be a hibernate bug?
Thank you...
You need to use TypeContributor extension point as described here.
https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#_extension_points
Example how it is done is at hibernate envers:
https://github.com/hibernate/hibernate-orm/blob/master/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml
NOTE: You should register type contributor in the bundle that does not use entity manager instance directly or indirectly. Otherwise your type contributor will not be used for entity manager creation. I spent a lot of time debugging this. It is better to have a separate bundle just for user types.