Fix toplink by switching to OpenJPA … ?

I recently ran into a post where someone said they were dropping TopLikn Essentials in favor of OpenJPA. At the time I was searching for some assistance in fixing some rather impossible to diagnose (mostly due to toplink’s incomprehensible stack traces) ClassNotFoundException. I eventually figured out that toplink’s class loader was broken in some way which I couldn’t fix, and that meant I couldn’t have my entity classes subclass something from some other jar. Or whatever, I haven’t fully diagnosed the problem, and instead decided to spend my time on getting OpenJPA installed.

This turned out to be quite easy – I just downloaded the openjpa binaries and copy the openjpa jar and lib/*.jar from that disitribution into glassfish/domains/domain1/lib, then changed my persistence.xml to specify OpenJPA as the persistence provider:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="db">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>db</jta-data-source>
...

Even though OpenJPA is more strict about not using field accesses when using property-mode fields (even inside the same class, you can’t use this.x) I’m so happy that it told me this with wonderfully clear error messages, it seems worth the effort to fix my code (by right-clicking a lot and picking Refactor > Encapsulate Field).

Thanks go to Sahoo for showing me how to do this:

http://weblogs.java.net/blog/ss141213/archive/2006/07/using_openjpa_a.html

Advertisements

9 Responses to Fix toplink by switching to OpenJPA … ?

  1. Alexis MP says:

    Hi, is this using Oracle’s app server or GlassFish? Or simply a Java SE app?

  2. dobes says:

    I’ve been using GlassFish V2-b58.
    So far I’ve also noticed that OpenJPA has its own issues – I had to convert my Map relationships into List in order to avoid “Unsupported type” errors and at least one of my queries is being accepted. Maybe I’ll try Hibernate …

  3. dobes says:

    Well I couldn’t figure out how to get either Hibernate or OpenJPAto work, so I removed all my shared code between GWT and the server side and now I use toplink again.

    TopLink gave me a descriptive, useful error that Hibernate tossed a useless stack trace for.

    I guess to diagnose problems in my JPA app I should try to run it in all three and hopefully one of them will give me a comprehensible error message. Of course, I still can’t share any code between my client jar and my server code, since toplink throws a ClassNotFoundException when it tries to load my entity class.

  4. dobes, have you tried to to move all your persistence (POJOs) classes to a separate jar, allocating it in EAR/lib folder – this way it will be visible for all packaged applications into this EAR – ejb’s, war’s, etc. Also this will give you the possibility to move the same jar to remote client, so it can also use your POJO’s objects. ?

    Regards,
    Dmitri

  5. dobes says:

    Thanks for the suggestion dmitri.

    Have you tried that yourself?

    In my experience, all the classes in the persistence unit must be in the same war file as the persistence.xml, and it seems like the jar file doesn’t support persistence.xml.

    Again, I still feel like I’m stumbling around in the dark on this one – I’ve got things “basically working” now, and I’m afraid to mess around for fear of breaking everything.

    Besides, giving the client access to the same persistent objects used in the server opens up a new batch of issues around security and performance that I’d rather have direct control over.

    For that reason, and because GWT doesn’t allow annotations on objects, I’m using a seperate set of classes for dealing which the client and a secure wrapper which translates to and from instances of database POJO’s and the client-side objects.

  6. Actually, you can place persistence.xml to any jar file, into META-INF folder, so you can move this jar file out of WAR but of course. In my enviroment, application is packaged into EAR file that contains several web applications (war files) as well as ejb and all JP classes along with persistence.xml are put into a separate api.jar that is put into EAR-ROOT/lib folder, I actually did it like examples, found in glassfish tutorials and it worked without any noted troubles. Here is the direct link I followed – https://glassfish.dev.java.net/javaee5/persistence/persistence_faq.html#7

    In your case (if WAR file is what you deploys into app server), the link, I suppose, is as follows: https://glassfish.dev.java.net/javaee5/persistence/persistence_faq.html#6

    But from experience of my past projects, separating JP POJO’s from pure client-only POJOs (data holders) might be a good thing anyway, as this allow you to transfer less amount of data to your client and might also be useful and simplier, when your JP POJOs are complex, using lazy collections etc.

    Regards,
    Dmitri

  7. dobes says:

    Okay, if I have a chance maybe I’ll give it another try. As it is I don’t need to do this, since I’ve worked around it already, but maybe sometime I will.

  8. Valery says:

    Actually it’s not a problem of Toplink, it’s caused by wrong Web Application Class loading in Glassfish. You shouldn’t have such problem in Tomcat or when deploying your Web Application application as an EAR in Glassfish.

  9. dobes says:

    Thanks, Valery. I guess I should be glaring at the glassfish team instead of the toplink essentials team?

    I am using glassfish as my container, so I suppose hibernate would be having the same problem as toplink. I haven’t tried it out, maybe I should, but I don’t need to now that I’ve made workaround for all of this.

%d bloggers like this: