You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Sergio Tabanelli <se...@actalis.it> on 2009/05/29 09:07:01 UTC

Fluid, SDO persistence with JPA

Hi all
My name is Sergio Tabanelli and I am currently working on an identity
management project. 
During the project inception we choose SDO as object entity abstraction api,
openjpa as persistence layer and fluid (apache labs project from Pinaki
Poddar http://people.apache.org/~ppoddar/fluid/site/index.html) as
connection layer between SDO and JPA. During development we spent 2 months
extending fluid functionality and correcting bugs (for example generation of
jpa pojo class on the fly and in memory using serp, enhance persist and
rollback functionality, add a changesummary driven applychanges method,
etc.). Now we have a framework that works quite well and is extensively used
across all our identity manager application. We are now releasing 
opensource our product (probably with an apache2 licence) together with the
patched version of fluid (source are already available at
https://sourceforge.net/projects/gaiusidm/ and
http://gaiusidm.svn.sourceforge.net/viewvc/gaiusidm/). I am sorry but, due
to delivery pressure, changes to fluid was not tracked and we don’t have a
descriptive change history, code was not commented and, I am afraid, but I
don’t remember all code changes we made (work was done 1 year ago). I put
all changes I remember in a small RELEASE_NOTES text file in the fluid
project root dir. 

Here are some useful notes:

to persist a new dataobject using the new SDOEntityManager.applyChanges
method:

// do some stuff with changesummary log active
dataGraph.getChangeSummary().beginLogging();
.....
.....
// end logging
dataGraph.getChangeSummary().endLogging();

// get an instance of the SDOEntityManager and then apply changes
SDOEntityManager em = (SDOEntityManager) emf.createEntityManager();
em.getTransction().begin();
em.applyChanges(dataGraph.getRootObject());
em.getTransaction().commit();

if you don't want to use custom applyChanges method but you still want to do
changesummary driven persistence, you can use the standard persist method
passing the SDO data graph as persisted object

// get an instance of the SDOEntityManager and then apply changes
EntityManager em = emf.createEntityManager();
em.getTransction().begin();
em.persist(dataGraph);
em.getTransaction().commit();

It must be mention also that changesummary driven persistence does not
persist the root dataobject but only contained dataobjects.

to use dynamically in memory JPA pojo class generation you must use the new
SDODynamicClassResolver, In persitence.xml ad the following line:

      <property name="openjpa.ClassResolver"
value="org.apache.openjpa.sdo.SDODynamicClassResolver"/>

see src/test/resources/MET-INF/persitence.xml for an example

If you want to simply persist a dataObject despite the changesummary use the
persist, merge or remove standard method passing a dataObject as persisted
object (do a merge first if needed). Example:

EntityManager em = emf.createEntityManager();
em.getTransction().begin();
dataObject = em.merge(dataObject); // needed only if detached
em.remove(dataObject);
em.getTransaction().commit();

There are some issues:
SDO type registration happens only on the first call to createEntityManager
method so you need to call this method before doing anything with the
persistent SDO types, alternatives should be investigated. 

Serp, the bytecode library used for JPA class generation, does not work with
enum annotation properties, needed for cascade type annotation, so on the
fluid source tree there is a patched version of the serp Annotation.java
class, if you don't want to patch serp you need to force classpath load
order to give precedence to the patched class version present in the fluid
jar (or if you are lucky....)

Some other notes on SDO root objects: 
normally my SDO XSDs does not have root objects, and I don't persist root
object. When I fetch from repository, dataobjects are returned without a
root and if I need to serialize or pass objects to "pure" SDO application I
use a new helper method to create and populate a new root object, this
method basically, create a new root SDO type on the same namespace of the
dataobject passed as argument, create a new root object and poupulate it
with all related objects. Example:

SDOEntityManager em = (SDOEntityManager) emf.createEntityManager();
DataObject dobj = em.find(dobjType, id);
dobj = ImplHelper.populateNewRootObject(dobj); //Create a new root object
and populate it with dobj and all related objects.

In the test source tree there is a simple ldap & ActiveDirectory
abstractstoremanager, that is tested through persistence of dataobject to
ldap and activedirectory, those tests use a stupid hack to avoid failures if
no ldap or AD is configured, they print errors but don't fail. If you want
to test ldap and AD you need to configure your openldap and/or AD in
persistence.xml (see src/test/resources/MET-INF/persitence.xml for an
example) in the fluid root dir there are a simple slapd.conf and gaius.ldif
that can be used for openldap configuration and basedn creation.

As I previously mention, coding was done with delivery pressure so I am sure
that some refactoring should be done….

Obviously suggestions, bug reporting and desiderata are more then welcome.
Pinaki already give me some good hits for enhancements…
Hoping that this work will be usefull to the openJPA community, again, my
thanks to Pinaki Poddar for the fluid project .
   
  
Ciao grazie 
Sergio Tabanelli

-- 
View this message in context: http://n2.nabble.com/Fluid%2C-SDO-persistence-with-JPA-tp2992382p2992382.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.