views:

791

answers:

3

I have classes that are named exactly the same across different plug-ins that I use for my application, and I'd like to be able to configure them properly with Hibernate. The problem is that it looks like Hibernate dynamically generates a class' package name when trying to find a class when it's doing its mapping. With one plug-in this scheme works, but across multiple plug-ins it's not working. It looks like Hibernate gets confused when dealing with Hibernate configuration files across multiple plug-ins.

Is this because each plug-in has its own class-loader? What is the best way to proceed to make this work with the existing plug-ins and Hibernate?

+3  A: 

The problem is, that every plugin has its own Classloader and Hibernate uses Reflection to find the right classes.

I have a very nice article at home about exactly this problem, but this one is in German. I will try to explain what you need to do.

In order to have the datastructure shared over several plugins, you have to put it in a plugin and enable a feature called buddy-policy. Lets say you have a main-application-plugin which is initiating hibernate on startup, this plugin needs to "see" the classes from the datastructure-plugin. To do this the main-plugin sets its Buddy-Policy to "registered" and the datastructure-plugin registers itself as a "buddy". Unfortunately you have to do this all directly in the manifest file, at least in 3.3 there was no way to do this in the editor.

Once this buddy-policy works, Hibernate will also.

I looked up my old application and here is how I did it.

  1. The main-application (toolseye.rcp) is dependent on the hibernate plugin (de.eye4eye.hibernate) and the datastructure-plugin (toolseye.datastructures)
  2. The hibernate-plugin specifies its buddy-policy as "registered"
  3. The datastructure-plugin registers itself to the hibernate-plugin

Here are the important lines:

Hibernate-plugin de.eye4eye.hibernate

Eclipse-BuddyPolicy: registered

Datastructure-plugin toolseye.datastructures

Eclipse-RegisterBuddy: de.eye4eye.hibernate

Put those line directly in the MANIFEST.MF

Both plugins need to reexport their packages in order that the main application or whatever layer you have in between can use them. Hope that helped.

lostiniceland
Very helpful, thanks much!
AlbertoPL
I added an example. If there are better architectural approaches to that I am interested as well. But that should describe how the buddy-mechanism works.
lostiniceland
Yes this helped much, thank you.
AlbertoPL
+1  A: 

Just to make this complete.

Instead of using Hibernate, EclipseLink could be used as JPA-provider in a Eclipse RCP application. EclipseLink is the former TopLink from Oracle and has been choosen to be the reference implementation for JPA 2.

The point for an RCP is, that EclipseLink is available as OSGI-Bundles (org.eclipse.persistence.jpa), and due to that it can load classes from another plugin without an additional buddy-policy.

Currently I was playing around, using the following project structure (Model-View-Presenter Pattern). The names in the brackets specify the dependecy plugins (not all are included, only the ones related to this question)

  • rcp.mvp.view (rcp.mvp.presenter / rcp.mvp.model)
  • rcp.mvp.presenter (rcp.mvp.data - data reexports the model, so this is not needed here) *
  • rcp.mvp.data (rcp.mvp.data.mysql / rcp.mvp.model / javax.persistence / org.eclipse.persistence.jpa)
  • rcp.mvp.data.mysql - provides only the mysql-jdbc-driver. has to be inside the classpath
  • rcp.mvp.model

In this scenario, the JPA provider in the data-plugin is able to load the classes from the model-plugin without a buddy-policy.

*Note, the presenter is not dependent on any JPA packages since this is encapsulated by DAOs (the main reason why to use them still)

Links

lostiniceland
A: 

Hepful!! May I have details form datastructure layer? (simple pjojo classes and xml file mapping ?)

ar_nang