[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] RCP-Eclipselink Classloader Problem

I'll do my best, maybe explaining our set up will help you.

Project:
 util.jpa: Contains a special EntityManagerFactoryFactory :) This
takes care of all the config in one place.

 It takes 2 parameters:
   String persistenceUnitName,
   ClassLoader yourClassLoader

So let's say i have my project
  myproj.model which contains entities, and a persistence unit. To
"connect" this project to EclipseLink, I just call:
EmfFactory.createEntityManagerFactory(MyActivator.PLUGIN_ID,
this.getClass().getClassLoader());  in the Activator of the plugin,
now i have an EntityManagerFactory that can be used in my project to
get new EntityManagers. So the EmfFactory handles creating the
database connection and setting up an EntityManagerFactory.

The golden rule with the OSGI stuff is Managed Entities CANNOT cross
classloader boundries. However, you can keep mappedsuperclasses in a
different classloader, that's fine.

If you would like more details about our RCP/OSGi set up please let me
know, I plan on creating a blog post about it anyway.

Hope this helps.


./tch



On Wed, Aug 6, 2008 at 7:22 AM, Markus Franz <markus.franz@xxxxxxxxxxx> wrote:
> Hi all,
>
> first and foremost: i am new to the whole ORM stuff, so please be gentle...
>
> While i already did some serious research into the usage of Eclipselink in
> RCP Applikations, i found no satisfactory answers as to how i can maintain
> the most flexibility with resspect to the underlying database as well as the
> stored entities.
>
> I will give you a quick sketch of what i am trying to accomplish:
>
> I want the something like following plugin structure:
>
>  - my.project.persistence (the Plugin providing the Eclipselink features to
> whoever needs them, defining Extension Points, e.g. for confoguration of the
> underlying database)
>
>  - my.project.persistence.derby (one of potentially many swappable plugins,
> extending the aforementioned Extension Points and delivering the database
> Drivers, Confogurations, etc.)
>
>  - my.project.model (one of potentially many plugins containing some kind of
> objects, which should be persisted)
>
>  - my.project.application (doing something with the objects from e.g.
> my.project.model and sometimes try to persist them using
> my.project.persistence)
>
>
> What i already got running is an extensibe mechanism to plug in the
> my.project.persistence.derby plugin on top of the my.project.persistence
> plugin. Some test object defined inside of the my.project.persistence plugin
> was successfully persisted into my derby DB. For convenience, i want
> something like the following to work:
>
> public static boolean save(Object o){
>
>                 boolean successfull = false;
>
>                 EntityManager em = getEntityManagerForObject(o);
>                 EntityTransaction tx = em.getTransaction();
>                 try
>                 {
>                     tx.begin();
>                     em.persist(o);
>                     tx.commit();
>                 }
>                 catch (Exception ex){
>                         ex.printStackTrace();
>                 }
>                 finally
>                 {
>                     if (tx.isActive())
>                     {
>                         tx.rollback();
>                     }
>                     else
>                         successfull=true;
>
>                     em.close();
>                     emf.close();
>                 }
>                 return successfull;
>         }
>
> with an EntityManager gotten like
>
> private static EntityManager getEntityManagerForObject(Object o) {
>
>                 IExtensionRegistry registry =
> Platform.getExtensionRegistry();
>                 IExtensionPoint point =
> registry.getExtensionPoint("my.project", "ORMConfiguration");
>                 String driver="org.apache.derby.jdbc.EmbeddedDriver";
>                 String dialect="jdbc:derby";
>                 for (IExtension extension : point.getExtensions()){
>                         for(IConfigurationElement element :
> extension.getConfigurationElements()){
>                                 driver = new
> String(element.getAttribute("JDBCDriverClass"));
>                                 dialect = new
> String(element.getAttribute("SQLDialect"));
>                         }
>                 }
>
>                 Map<String, Object> properties = new HashMap<String,
> Object>();
>
>                 properties.put("eclipselink.ddl-generation",
> "create-tables");
>                 properties.put("eclipselink.ddl-generation.output-mode",
> "both");
>
>                 properties.put("eclipselink.jdbc.url",
> dialect+":MYDBPATH;create=true");
>                 properties.put("eclipselink.jdbc.user", "user");
>                 properties.put("eclipselink.jdbc.password", "password");
>                 properties.put("eclipselink.jdbc.driver", driver);
>
>                 properties.put("eclipselink.jdbc.read-connections.min",
> "1");
>                 properties.put("eclipselink.jdbc.write-connections.min",
> "1");
>
>                 properties.put("eclipselink.logging.level" , "FINE");
>                 properties.put("eclipselink.logging.timestamp", "false");
>                 properties.put("eclipselink.logging.session", "false");
>                 properties.put("eclipselink.logging.thread", "false");
>
>
> ////////////           THIS IS THE POINT OF INTEREST:
> ///////////////////
>
>
>                 properties.put(PersistenceUnitProperties.CLASSLOADER,
> o.getClass().getClassLoader());
>
>
> ////////////////////////////////////////////////////////////////////////////////////
>
>
>
>                 try {
>                         emf = new
> PersistenceProvider().createEntityManagerFactory("my.project", properties);
>                 } catch (Exception e) {
>                         // TODO Auto-generated catch block
>                         e.printStackTrace();
>                 }
>
>                 EntityManager em = emf.createEntityManager();
>
>                 return em;
>         }
>
>
> A Simple Application (in my.project.application) might now take some Object,
> let's call it CrashTestDummy ctd1 from my.project.model (where its mapping
> information is also stored, let's say in a regular orm.xml file) and just
> call my.project.persistence.Utility.save(ctd1) and eclipselink would do it's
> magic. I do not know, if this is bad practice, but it seemed to me to be a
> reasonable approach, if i do not want to touch the my.project.persistence
> plugin ever again, when i am developing some my.project.model.newstuff style
> plugins.
> The trouble is that without referencing the classloader of the persisted
> object (i.e. commenting out the indicated line above), there is no trouble
> loading the database driver and all, but no mapping for the object is found.
> If i try to run it with the objects Classloader, the output indicates that
> the mapping is indeed found, but alas not the derby driver!
>
> I assume, this is somehow related to some of the old questions on this
> mailing list concerning OSGI but i am also not exactly an OSGI crack and
> therefore could not entirely understand all comments.
>
> Regards
>
> Markus
>
>
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>
>