Hi Bengt, That sounds like a reasonable approach, just remember to be careful if any of the database schemas evolve independently of one another as you'll no longer have a common mapping for all the persistence units, and will need to use xml mappings to ensure that all of the "evolved" persistence units work correctly.
Unfortunately this is one of those times where the principles of good Object Oriented design become difficult to apply because there is (by necessity) tight coupling between the implementation of the Entity classes, the Database tables and the persistence unit definition. Regards, Tim ________________________________ > Date: Mon, 20 Sep 2010 09:49:46 +0200 > Subject: Re: AW: OSGi JPA and JDBC Services > From: [email protected] > To: [email protected] > > Thanks Tim. > > In the future I will probably want to use load-time weaving which > probably means I'll have to re-architect a little bit. I guess one way > of doing that is to still keep the common classes in separate maven > projects but embed them in the bundles that use them (maybe using > "Private-Package"). Do you think that would be a "good practice" in > situations like this? > > /Bengt > > 2010/9/19 Timothy Ward >> > > Hi Bengt, > > It's actually a violation of the JPA service specification, rather than > the JPA specification, which doesn't talk about OSGi at all. A > persistence unit and its entities are intimately related, the > persistence unit can specify overrides for entity mapping metadata, and > it defines the database that is used. This is a very tight coupling, > and so the artefacts should live in the same bundle. > > The restriction is further added so that once bytecode weaving is > supported in OSGi it will be possible to weave the entity classes. If > the classes live in a different bundle then the JPA runtime cannot > guarantee to weave them before they are first used (after which time > they can no longer be woven). It is also a problem if you have multiple > persistence units using different JPA providers, it is also not > possible for entity classes to be woven by multiple providers (well it > might work sometimes, but almost certainly not). > > Given that you are pre-enhancing, and using a single JPA provider, what > you are doing will almost certainly be fine, but it's not guaranteed to > be portable. Normally the way to do this is to package all of the > managed classes in a single bundle that defines the persistence unit. > If there are common structures between the database tables for > different persistence units, then those persistence units should be > packaged in the same bundle, along with the common superclass. > > I'm not suggesting that you should re-architect your application, I > just want people to be aware that if your entities are not defined in > the same bundle as your persistence unit then they are not guaranteed > to work portably, and not all features are guaranteed to work either. > > Regards, > > Tim > > ________________________________ >> Date: Sat, 18 Sep 2010 14:55:57 +0200 >> Subject: Re: AW: OSGi JPA and JDBC Services >> From: [email protected] >> To: [email protected] >> >> Tim, >> >> Technically it's not allowed for entities to be in separate bundles >> from the persistence descriptor that uses them, its a violation of the >> encapsulation of the data model. >> >> All my entities inherit from a common base class, EntityBase. It is an >> abstract class annotated with @MappedSuperclass. I use it for >> attributes that all my entities have such as CreatedBy, CreatedWhen, >> etc. >> >> Since EntityBase is used by classes that reside in many different >> bundles (with different persistence descriptors), it resides in a >> "util" bundle that has no persistent descriptor at all. Is this a >> violation of the JPA spec? How would one handle a scenario like this >> then? >> >> BTW, this seems to work with OpenJPA and Aries. I enhance my JPA >> classes at build time (included EntityBase). >> >> /Bengt >> >> 2010/9/18 Timothy Ward >>> >> >> Hi, >> >> I'm glad that you have a basic application up and running. I have a few >> comments. >> >> Technically it's not allowed for entities to be in separate bundles >> from the persistence descriptor that uses them, its a violation of the >> encapsulation of the data model. It will probably work in most >> environments, but only for pre-enhanced entities. I would strongly >> recommend not putting entities into a different bundle from the >> persistence descriptor, primarily because it is explicitly forbidden in >> the JPA service specification. >> >> As for the JPA provider, there is a minimum level of OSGi awareness >> necessary. Firstly, it needs to be packaged as an OSGi bundle. Secondly >> it needs to register its PersistenceProvider implementation in the >> service registry (using some service properties defined in the JPA >> service specification). Both of these things are easy for a user to >> package in, but have already been done by OpenJPA and EclipseLink. If >> you wanted to to use Hibernate, then you would almost certainly need to >> re-package it, and use blueprint, DS, or an Activator to register the >> service. >> >> It should be possible to use EclipseLink with the Aries JPA container, >> there were some bugs when we originally tested it, which we raised >> against them. I don't know if they've been fixed yet, but I'd be happy >> to set up some more itests if you were interested. >> >> The "incompatible" approach taken by EclipseLink is actually the >> support that the JPA service specification was built upon. >> Meta-Persistence is an OSGi defined header for doing JPA in OSGi, it's >> more or less identical to the JPA-PersistenceUnits header. >> >> I will take this opportunity to say that EclipseLink's OSGi support is >> different to the JPA container in Aries. EclipseLink implements the JPA >> service specification, which defines unmanaged JPA in OSGi, Aries uses >> the same metadata (Meta-Persistence) and spec defined integration (the >> PersistenceProvider service) to do container managed JPA. As a result, >> the Aries JPA container does not implement a standard (but does use >> OSGi standards). The advantage that Aries has is that it theoretically >> works with any JPA provider (barring bugs in their implementations), >> whereas as far as I am aware EclipseLink is the only provider that can >> be used with the JPA service specification. >> >> Regards, >> >> Tim >> >> ---------------------------------------- >>> From: [email protected] >>> To: > [email protected] >>> Date: Fri, 17 Sep 2010 17:37:01 +0200 >>> Subject: AW: OSGi JPA and JDBC Services >>> >>> Good news: >>> >>> - I'm now using the following persistence.xml >>> >>> >>> transaction-type="RESOURCE_LOCAL"> >>> osgi:service/javax.sql.DataSource >>> test.openjpa.model.Book >>> true >>> >>> >>> - I've added the three bundles org.apache.aries.jndi.api, jndi.core >> and jndi.url to my application. >>> >>> - I have another bundle which imports the appropriate JDBC driver and >> publishes a data source as an OSGi service. >>> >>> A simple test case with just one entity in the PU bundle now works. >>> >>> My real application is a bit more complex, the PU bundle imports >> entity classes from two other bundles, and there are custom value >> handlers which need to be loaded by OpenJPA in addition to the entity >> classes. This is the next thing I'm going to try. >>> >>> Just for my better understanding: does the JPA provider have to be >> OSGi aware to make this setup work? I.e. does OpenJPA now work with >> Aries because the OpenJPA guys have made some additions in the past? Or >> would the same example also work with Hibernate or Eclipselink? >>> >>> Eclipselink supports OSGi out of the box (while Hibernate notoriously >> doesn't), but their approach appears to be slightly incompatible, e.g. >> they use a JPA-PersistenceUnits manifest header instead of >> Meta-Persistence. >>> >>> Best regards, >>> >>> Harald >>> >>> >>> ________________________________________ >>> Von: Timothy Ward >> [[email protected]] >>> Gesendet: Freitag, 17. September 2010 16:57 >>> An: > [email protected] >>> Betreff: RE: AW: OSGi JPA and JDBC Services >>> >>> You're absolutely right, that was supposed to say 'true' not 'false' >> - whoops! >>> >>> Tim >>> >>> ---------------------------------------- >>>> From: [email protected] >>>> To: >> [email protected] >>>> Date: Fri, 17 Sep 2010 16:53:49 +0200 >>>> Subject: AW: OSGi JPA and JDBC Services >>>> >>>> Hi Tim, >>>> >>>> 1. I do enhance my classes at build time. >>>> 2: I do not list all classes in the persistence.xml. >>>> >>>> So I believe you're meaning to say that true would avoid my problem >> because OpenJPA would not need to scan from the persistence unit root. >> That makes sense - I'll give it a try... >>>> >>>> Best regards, >>>> Harald >>>> >>>> >>>> ________________________________________ >>>> Von: Timothy Ward >> [[email protected]] >>>> Gesendet: Freitag, 17. September 2010 16:36 >>>> An: >> [email protected] >>>> Betreff: RE: AW: OSGi JPA and JDBC Services >>>> >>>> Hi Harald, >>>> >>>> I have two questions: >>>> >>>> 1. Are you pre-enhancing your Entity classes? This is a requirement >> using the base Aries JPA container as load-time weaving cannot be >> supported in a generic OSGi framework (although some runtimes extend >> the Aries code to provide this, e.g. Geronimo and WebSphere). >>>> >>>> 2. Are you listing all of your entity classes in the persistence >> unit definition and setting false? In unmanaged JPA you are supposed to >> do this (though many providers support scanning in unmanaged >> environments). In OSGi scanning doesn't work the same way, and is, once >> again, not supported in the Aries JPA container (though it is provided >> in WebSphere). >>>> >>>> Both of these limitations will (hopefully) be lifted in the future, >> but they will need to rely on features proposed for version 4.3 of >> OSGi, and so there's not a lot we can do about them at the moment. >>>> >>>> Regards, >>>> >>>> Tim >>>> >> >> > >
