-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Unknown Entity when using several Eclipse Plug-Ins
PostPosted: Fri Nov 10, 2006 2:22 pm 
Newbie

Joined: Fri Nov 10, 2006 12:32 pm
Posts: 7
Hello Hibernate-Community

I'm using Hibernate 3.2.0 with annotations in Eclipse 3.2.1 plug-ins and I have the following intention:

I would like to encapsulate the Hibernate libs and the session handling in a single plug-in, called org.myplugin.hibernate. This plug-in defines an extension-point: Extensions provide the classes that should be mapped and for this, they have to implement my interface IModelProvider. The mappings are specified by annotations. My goal is to provide a flexible mechanism for adding new datamodels to my application. Currently, there exists one extension for testing-purpose - org.myplugin.hibernate.test - that contributes a trivial class for mapping:

Code:
import javax.persistence.*;

@Entity
public class TestClass {
   private Long id;
   private String str = "Hello World";
   
   @Id
   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public String getStr() {
      return str;
   }

   public void setStr(String str) {
      this.str = str;
   }
   
   public String toString(){
      return str;
   }
   
}


When org.myplugin.hibernate is loaded, it queries the Eclipse extension registry for extensions to its extension point. For each extension that was found, it gets the annotated classes by invoking IModelProvider.getAnnotatedClasses().

For example, org.myplugin.hibernate implements IModelProvider as follows:

Code:
public class TestModelProvider implements IModelProvider {

   public Class[] getHibernateAnnotatedClasses() {
      Class[] result = {TestClass.class};
      return result;
   }

}


org.myplugin.hibernate then creates a configuration, adds the mappings, creates a session factory and session respectively:

Code:
Class[] annotatedClasses = myModelProvider.getHibernateAnnotatedClasses();
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass(annotatedClasses[0]);
...//configure database credentials
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();


Until here, everything seems to work fine.

Now, org.myplugin.hibernate publishes a proxy for saving instances of mapped objects. Basically it implements the following method:

Code:
public void saveObject(Object saveableObject) {
   session.save(saveableObject); //session is the Hibernate session created above
}


Whenever an instance of TestClass is passed to this method for making it persistant, I encounter the following exception (I have included the full stacktrace at the end of my post):

Quote:
org.hibernate.MappingException: Unknown entity: org.myplugin.hibernate.test.TestClass
at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:548)
...
.

After extensive reading, I'm now aware that this is an issue concerning classloaders - org.myplugin.hibernate uses another classloader than org.myplugin.hibernate.test. Consequently, I DID introduce buddy loading as proposed in Hibernate and Eclipse Integration. I'm confident that I did this correctly, since I'm now able to do the following (which I wasn't before) in org.myplugin.hibernate:

Code:
public void saveObject(Object saveableObject) {
   try {      
Class.forName(saveableObject.getClass().getCanonicalName()); // No Exception occurs - the class is loadable!
   } catch (ClassNotFoundException e) {
      e.printStackTrace();
   }
   //session.save(saveableObject); <-- still throws a MappingException!
}


Saving triggers still the same exception as before - it seems (I'm speculating; I'm not quite sure, what's happening) that, despite of the buddy loading, Hibernate is not able to recognize the class TestClass. I assume that telling Hibernate to use the classloader provided by saveableObject.getClass().getClassLoader() would overcome my problem, but obviously, that is not possible/intended by the Hibernate developers.

Any ideas how to solve my problem?

Thanks in advance,

Michael

Complete Stacktrace:
Quote:
org.hibernate.MappingException: Unknown entity: org.evolizer.hibernate.test.TestClass
at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:548)
at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1338)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:96)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519)
at org.evolizer.hibernate.session.EvolizerSession.saveObject(EvolizerSession.java:56)
at org.evolizer.hibernate.test.EvolizerSessionTest.testSaveObject(EvolizerSessionTest.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)
at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:58)
at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:24)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
at org.eclipse.core.launcher.Main.run(Main.java:977)
at org.eclipse.core.launcher.Main.main(Main.java:952)



Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 5:56 am 
Newbie

Joined: Fri Nov 10, 2006 12:32 pm
Posts: 7
The issue mentioned above is still unresolved. One of my co-workers copied my text and posted the same question at eclipseZone.com.

Over there, a more promising discussion has developed than here. ;-)

Perhaps someone can contribute to the thread mentioned above or at least use it for her/his own work, so I would like to provide a link to it: Plug-Ins & Hibernate at eclipseZone.com.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 11:31 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
well since this question have been answered multiple times in this forum already it shouldn't really be necessary should it ? :)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 11:57 am 
Newbie

Joined: Fri Nov 10, 2006 12:32 pm
Posts: 7
Mhm, I beg you pardon but I (and two co-workers of mine) have spent several hours reading through posts on this topic. The conclusion was usually: "Use buddy loading". - Which I did (see above) and which did not resolve my problem.

So, perhaps you can provide me a link to an answer which is a bit more elaborate than a single line consisting of "use buddy loading + Hibernate and Eclipse Integration".

Thanks in advance,

Michael


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 12:03 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
i'm quite sure you haven't setup buddy classloading correctly because then it would work.

I don't have time now to write all the steps you need to do for this, but I would suggest you go to an eclipse/osgi forum since it is there the issue stem's from (namely not using/supporting the java classloading model out-of-the-box)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 12:20 pm 
Newbie

Joined: Fri Nov 10, 2006 12:32 pm
Posts: 7
Thanks for your reply.

Quote:
i'm quite sure you haven't setup buddy classloading correctly because then it would work.


Can you confirm that buddy-loading also works with annotations? - I have read several buddy-loading how-to's and followed the instructions closely (and of course, I have tried a lot of stuff on myself).

So, in plug-in 'A', I CAN create instances of my business entities, residing in plug-in 'B', using the Class.forName()-mechanism - without having introduced any other dependencies than buddy loading.

But when I register my business entities to the AnnotationConfiguration, something goes wrong during secondPassCompile().

Quote:
but I would suggest you go to an eclipse/osgi forum since it is there the issue stem's from (namely not using/supporting the java classloading model out-of-the-box)


That's exactly what I did (or my co-worker respectively - see my second post in this thread). Unfortunately, I have only received answers concerning xml-mappings - but not annotations - so far.

Regards,

Michael


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 1:46 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
buddyclassloading does not have to do with Class.forName loading, but via the current thread context classloader.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 24, 2006 6:25 am 
Newbie

Joined: Fri Nov 10, 2006 12:32 pm
Posts: 7
Yes, but Class.forName() uses the current classloader to look for and load the requested class (see http://wiki.eclipse.org/index.php/Conte ... hancements) and therefore you can use this mechanism to test whether buddy loading works or not.

You can easily verify this behaviour by defining two independent plug-ins, let's call them again 'A' and 'B':

In plug-in 'A', you attempt to load a class foo.Bar from plug-in 'B' by invoking Class.forName("foo.Bar") or - of course - Thread.currentThread().getContextClassLoader().loadClass("foo.Bar").

This will FAIL with a ClassNotFoundException, unless you introduce buddy-loading (or a Require-Bundle-Entry), i.e. add "Eclipse-BuddyPolicy: registered" to A's manifest and "Eclipse-RegisterBuddy: A" to B's manifest.

As mentioned above, as soon as I introduce buddy-loading, I can load the class foo.Bar by using Class.forName() and similar mechanisms. I can even register the class with the AnnotationConfiguration via addAnnotatedClass(). But I cannot make instances of foo.Bar persistent.

Please let me ask again: Can you confirm that buddy loading is also applicable, when using annotations instead of xml-mappings?

Regards,

Michael


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 24, 2006 9:08 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
from that page:

"Class forName

A classic Java mechanism for dynamic class discovery and loading. It uses the current classloader to look for and load the requested class. The current classloader is the classloader that loaded the class containing the method executing the forName(String) call."

That is *not* the current thread's classloader....again I do not believe you are using buddy classloading correctly.

And yes, annotations should work fine. If they don't then prove it by showing that using hbm.xml works, but annotations don't for the exact same mapping.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 25, 2006 8:26 am 
Regular
Regular

Joined: Sat May 20, 2006 3:49 am
Posts: 78
perhaps you could post the MANIFEST.MF files of your plugins? I have a similar architecture for my plugins, and for me it works fine.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 25, 2006 1:58 pm 
Newbie

Joined: Fri Nov 10, 2006 12:32 pm
Posts: 7
I have uploaded a prototype plug-in here.

The manifests look as follows:

Quote:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Test Plug-in
Bundle-SymbolicName: org.myproject.hibernate.test;singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: org.myproject.hibernate.test.Activator
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime,
org.myproject.hibernate,
org.junit4
Eclipse-LazyStart: true
Eclipse-RegisterBuddy: org.myproject.hibernate
Bundle-ClassPath: lib/hibernate-annotations.jar,
lib/ejb3-persistence.jar,
.


and

Quote:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Hibernate Plug-in
Bundle-SymbolicName: org.myproject.hibernate;singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: org.myproject.hibernate.Activator
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime
Eclipse-LazyStart: true
Eclipse-BuddyPolicy: registered
Export-Package: org.myproject.hibernate.sessionwrapper,
org.myproject.hibernate.api
Bundle-ClassPath: lib/log4j-1.2.11.jar,
lib/jta.jar,
lib/hibernate-annotations.jar,
lib/hibernate3.jar,
lib/ejb3-persistence.jar,
lib/ehcache-1.2.jar,
lib/dom4j-1.6.1.jar,
lib/commons-logging-1.0.4.jar,
lib/commons-collections-2.1.1.jar,
lib/cglib-2.1.3.jar,
lib/asm-attrs.jar,
lib/asm.jar,
lib/antlr-2.7.6.jar,
.,
lib/mysql-connector-java-3.1.14-bin.jar


--Michael


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 25, 2006 2:39 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
why do you have certain libraries duplicated across these two manifests ? like ejb3-persistence and hibernate-annotaitons ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 26, 2006 6:38 am 
Regular
Regular

Joined: Sat May 20, 2006 3:49 am
Posts: 78
Could you please try to change the Eclipse-LazyStart Parameter to false?

Perhaps it is time to write an Hibernate-in-Eclipse-RCP-integration guide. A lot of people have problems getting Hibernate to run in Eclipse. There is no detailed description available how to integrate Hibernate in the Eclipse Rich Client Platform.

I would be interested to work out some best practices with other Eclipse RCP developers how to integrate Hibernate into RCP and make them available to the Hibernate Community.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 26, 2006 6:46 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
feel free to add/explain more at http://hibernate.org/311.html

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 26, 2006 7:04 am 
Regular
Regular

Joined: Sat May 20, 2006 3:49 am
Posts: 78
Yes, I will add an overview and a detailed description of my Hibernate-Eclipse architecture in the next weeks.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.