Hi,
I’m looking at hibernate integration in an OSGi environment and would like to use JPA.
The example use case is the annotated entity objects are located in one bundle (dogs
), and we’re trying to persist a “Dog” object from code outside that bundle.
We also have a requirement not to have a persistence.xml file.
So I created a custom implementation of PersistenceUnitInfo
and create an EntityManagerFactory
like so:
EntityManagerFactoryBuilderImpl(
PersistenceUnitInfoDescriptor(
CustomPersistenceUnitInfo(
"somename",
listOf("dogs.Dog"),
mapOf(
"javax.persistence.jdbc.driver" to connectionDetails.driver,
"hibernate.dialect" to connectionDetails.dialect,
"javax.persistence.jdbc.url" to connectionDetails.url,
"javax.persistence.jdbc.user" to connectionDetails.username,
"javax.persistence.jdbc.password" to connectionDetails.password,
"hibernate.show_sql" to "true",
"hibernate.hbm2ddl.auto" to "update"
).toProperties(),
bundleClassloader
)
),
emptyMap<Any, Any>(), bundleClassloader
)
.build()
However, where this goes wrong is in the categorizeAnnotatedClass
method of the AnnotationMetadataSourceProcessorImpl
class, specifically:
xClass.isAnnotationPresent( Entity.class )
returns false because the annotation for xClass
(dogs.Dog
in the “dogs” class loader) is in the javax.persistence-api
bundle class loader, while and Entity
is in the main application class loader.
I believe it would work if instead hibernate did something like:
xClass.isAnnotationPresent(Class.forName(Entity.class.name, false, ((JavaXClass) xClass).clazz.getClassLoader()))
As the annotation interface should always be in the classloader for the annotated class.
Is there a way to resolve this? Or a different approach I should be using?
Any pointers would be appreciated.
For reference, I am using hibernate-core:5.5.7.Final and hibernate-osgi:5.5.7.Final.