Eclipse4 RCP - No Persistence provider for EntityManager

#1

Hello,

I'm developing an Eclipse4 RCP application which uses ObjectDB and have the following problem
after calling Persistence.createEntityManagerFactory("test.odb") :

javax.persistence.PersistenceException: No Persistence provider for EntityManager

I'm using the latest ObjectDB 2.6.2.b03. It is integrated in our target platform.
It is noticed that since 2.6.2.b02 there is no more integrated javax.persistence & javax.transaction.

The simplified project structure is the following one :

Project X (Plugin Project with a product file to start the application)
- product dependencies are added : objectdb, javax.persistence, javax.transaction

- javax.persistence is imported in the plugins manifest 

after the bundle is activated I'm calling 

Persistence.createEntityManagerFactory("test.odb");

 

which throws the error. I think it has something to do with the Classloading of the javax.Persistence und ObjectDB bundles and also tried Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); before the call of createEntityManager (this "trick" was mentioned here in the forum some time ago) but the error still occures.
 

I would highly appreciate if somebody could give me an advice how to fix that error. ObjectDB is a very nice database and we look forward to buy the commercial version of it.

kindly regards,
Patrick

#2

Please advice if this problem is new since build 2.6.2_02.

You can still use objectdb.jar with JPA bundled in the same JAR also after build 2.6.2_02. It is not available on Maven but if you download ObjectDB you can find the objectdb.jar in the bin directory.

ObjectDB Support
#3

Thank you for the fast response. I can reproduce this problem also with EE Version 2.6.2.b01.
I just tried 2.6.2.b03 with JPA included and all works like a charm.

#4

ObjectDB runs fine now with JPA included. I have another question regarding the persistence.xml.
I put it in my /META-INF folder in the plugin project (also tried the src folder itself) but it seems that
it don't get found if I call Persistence.createEntityManagerFactory("my-pu");

Would be glad If somebody can tell my what else I have to consider?

Many thanks in advance

#5

You may try embedding it into objectdb.jar, although not very pretty.

Alternatively, see this forum thread and the solution at post #13 on that thread.

ObjectDB Support
#6

I can't modifiy the objectdb.jar... its provided in our Target Platform and I'm just adding this Bundle in the Product Configuration File.

Anyway I found at least a way to "register" my entity classes via 

emf.getMetamodel().entity(clazz);

Now I got another Problem...

This code works :

storageSvc.registerEntity(LocalEntity.class);
storageSvc.insert(new LocalEntity());
List<LocalEntity> l = storageSvc.selectAll(LocalEntity.class);
LocalEntity e = l.get(0);

When I run the code a second time (without the insert) I get a ClassCastException (LocalEntity cannot be cast to LocalEntity)... I know it's a ClassLoader Problem. The Entity class I get via the selectAll() is loaded by ObjectDB's ClassLoader whilst the Entity in the last line of the above Code is loaded by the plugins ClassLoader.

I have no clue how to solve that Problem. Setting the Context Classloader doesn't seem to work. The Project structure is the following one :

 

Plugin project A
- contains the LocalEntity class

Plugin project B
- Project A is dependency of this project
- contains an OSGi Service which provides the access to the ObjectDB database

Plugin project client
- uses the OSGi Service
- ObjectDB Bundle is set as Dependency in the product.configuration File 

 

#7

I tried again with the ContextClassLoader and the following works :

emf = Persistence.createEntityManagerFactory(uri);
Thread.currentThread().setContextClassLoader(LocalEntity.class.getClassLoader());
em = emf.createEntityManager();

but I hope there is a more confident way to get around these ClassLoader issues

#8

If setting the context class loader works only this way (i.e. between building an EntityManagerFactory to building an EntityManager) it may be because resources that are needed by createEntityManagerFactory (e.g. persistence.xml) are not available in LocalEntity location, so you can change the context class loader only later.

You may be able to avoid changing the context class loader by following ideas from the forum thread mentioned above. Particularly, for ObjectDB to be able to access resources and entity classes without changing class loaders its bundle must have access to classes and resources in relevant bundles with configuration and entity classes.

ObjectDB Support
#9

Thank you very much. I also created a Bundle Fragment and all works like a charm! Persistence.xml is now found and ClassLoader problems are gone... thats a suitable solution for now!

Reply