← Prev in month ← Prev in thread
Next in thread → Next in month →

AW: [sdo] ISSUE 134: JAXBHelperContext

From
Barack, Ron <>
Date
2009-02-09T13:49:58+00:00
ID
Thread
AW: [sdo] ISSUE 134: JAXBHelperContext
Title: ISSUE 5 and ISSUE 22: Discussion of JAXB

Hi Blaise, All,

 

I 
think for most of the companies in the TC, integration with JAXB is an 
absolutely critical usecase.  And since it's so important, everyone either 
already has or is going to implement something to support this use case.  
The motivation for standardizing JAXBHelperContext in 3.0 is that 

 

1) It makes SDO stronger, since there is a standard way 
to handle a critical use case.

2) It will only get harder to standardize it in the 
future, since everyone with an existing solution and we will have a hard time 
finding a solution that will be "backwards compatible" for 
everyone.

 

That said, maybe it is a good idea to defer this 
proposal at least until we have some framework proposal for creating 
HelperContexts.

 

What this means as far 
as the vF2F agenda is that the discussion of "integration with standard 
representations" will be limited to low level XMLHelper methods, such as 
creating and processing XMLStreamReaders and 
ContentHandlers.

 

Does everyone agree with 
this approach?

 

 

Ron

 

Von: Blaise Doughan 
[mailto:] 
Gesendet: Dienstag, 3. Februar 
2009 19:54
An: Barack, Ron
Cc: 

Betreff: Re: [sdo] ISSUE 134: 
JAXBHelperContext

Hi Ron,

For our implementation wrap is based on object 
identity not equals()/hashCode().  Below is some JUnit code adapted from 
one of our test cases to demonstrate.

    assertEquals(p1, 
p2);
    assertNotSame(p1, p2);
    
DataObject p1DO = jaxbHelperContext.wrap(p1);
    DataObject 
p2DO = jaxbHelperContext.wrap(p2);
    assertNotSame(p1DO, 
p2DO);

@XmlID (from JAXB) does not factor into identity past the 
scope of a load/save operation.  It is unlike @Id (from JPA) where POJOs 
with the same ID value are strongly related in that they correspond to the same 
row in some table.

Managing the scope of JAXBHelperContext is 
important.  For our implementation weak references are used where 
possible.  We also see the need for additional APIs to allow POJOs to be 
dereferenced under the user control.

Some of the changes being proposed 
by Frank appear to be making it easier for users to control 
HelperContexts.  This work might alleviate some of your concerns in that 
area.

I'm not sure I see the value in making JAXBHelperContext part of 
the SDO specification.  Again with potential changes to HelperContext 
creation, it could become possible for implementors to offer special purpose 
HelperContexts like this for handling of things like JAXB objects, XML, 
EMF,  etc. 

-Blaise

Barack, Ron wrote: 
 
type="cite">
  
  
Hi Blaise,

  
 

  
Some more questions on your implementation of 
  JaxbHelperContext

  
hc.wrap(Object) always returns the same DataObject 
  for the same pojo.  Does this rely on the equals() and hash() methods as 
  implemented in the class?  Imagine 2 pojos, where p1!=p2 but 
  p1.equals(p2).  Would hc.wrap(p1)==hc.wrap(p2)?  What about if 
  p1.class has some @XmlID field?

  
 

  
Looking at your sample, it's a little hard to discern 
  the lifecycle of the JaxbHelperContext.  Because constructing the types 
  is expensive (involving parsing XSDs, etc), I normally think of HelperContexts 
  as having to be thread-safe and shared, like a JAXBContext, or like a 
  classloader.  For instance, when a session bean uses SDO, there 
  would be one HelperContext that are shared by all instances of the bean.  
  I believe this to be the common 
  understanding.   The sample code is of course a simple 
  client; it's impossible to tell if the JaxbHelperContext is meant to 
  shared.

  
 

  
I think there is reason to have maybe 
  JaxbHelperContext be a sort of lightweight context, that is meant to be owned 
  by a single client.  We could have a heavyweight context, with types 
  defined by the XSD.  The heavyweight context could have a 
  method, something like 
  HelperContext.getJaxbHelperContext(JAXBContext).  The JaxbHelperContext 
  would basically delegate to the heavyweight context, except when doing things 
  like constructing instances, or implementing wrap() or 
  unwrap().

  
 

  
This gives me something like a binder, a client 
  object that I can use to control the scope and lifetime of the POJO -> 
  DataObject map.  But without defining a new "Binder" 
  interface.

  
 

  
Any comments?

  
 

  
Ron

  
 

  
 

  
 

  

  

  
  Von: Blaise Doughan [mailto:] 
  
Gesendet: Montag, 26. Januar 2009 16:08
An: Barack, 
  Ron
Cc: 
Betreff: 
  Re: AW: [sdo] ISSUE 5 and ISSUE 22: Discussion of JAXB

Hi 
  Ron,

From our perspective JAXBHelper context is the POJO Helper 
  Context.

Assuming the POJOs are also JPA entities, then wrapping (as 
  opposed to copying via an XML step) need not trigger all the lazy 
  relationships (of course this could be implementation dependent).  With 
  regards to wrapping and the performance of getters/setters, there are some 
  ways to do this with reasonable performance.

The POJO as a DataObject, 
  this is an interesting concept.  One problem I see with this is that 
  DataObjects do a lot of relationship management that most POJOs don't do (i.e. 
  adding a DataObject to a new container automatically removes it from the old 
  container).  Here the weaving is not invisible to the user and may not 
  match the users expecations.

The XSDHelper.define() call is necessary, 
  because as you have previously mentioned XML schemas generated from POJOs do 
  not contain all the information required by SDO.  One example is 
  specifying datatype=false/containment=false properties, that require SDO 
  annotations on the XML schema.

Does  DataObject 
  customerDO = hc.wrap(customer); always return the same DataObject?
In our implementation wrap always returns the same 
  DataObject.  This does require some management, but with proper attention 
  to object identity, and avoiding hard references it is doable.  Not sure 
  how a "binder" solution avoids this as something JAXB like would require a 
  one-to-one correspondence between a POJO and a DataObject.

What happens if a wrapped POJO is modified? 
  
Our 
  customer base is not interacting with both the POJO and the DataObject at the 
  same time.  If they were you are correct that weaving could be used to 
  apply the changes made to the POJO back to the DataObject.

Is there 
  any way to start with a DataObject, and generate a JAXB from it?
Yes, 
  this was the main reason for making the entry point its own 
  HelperContext.  DataFactory.create() creates DataObjects that wrap POJOs, 
  and XMLHelper loads DataObjects that wrap POJOs.

Usage of 
  StAX
The usage of StAX does not automatically create a Java SE 6 
  dependency.  JAXB 2.0 based on Java SE 5 makes use of these APIs, it just 
  requires implementors to ship the StAX (JSR 173) API jar.  I think SDO 
  should offer the same marshal/unmarshal options as JAXB.  But the 
  decision to change the base Java SE version is independent from our inclusion 
  of StAX.

User Expectations of the XML representation of 
  POJOs
You are correct in your model that the user must specify JAXB 
  information to get the desired XML representation.  This is exactly the 
  role of JAXB in the larger world of Java EE.  Today users are retrieving 
  data from relational databases as POJOs using JPA, and exposing this data 
  through services as XML using JAXB.

SDO competing with 
  JAXB
If SDO takes a POJO graph and has its own XML representation then 
  yes it is competing with JAXB.  Regardless of the algorithm it is 
  impossible to guess the XML schema representation of a set of POJOs, as such 
  annotations are required fix it.  With your proposal SDO annotations 
  would be required to adjust the XML Schema representation of a set of POJOs, 
  again this competes with JAXB.

Advantages of our 
  Approach

  
    
A single integration point between SDO and Java EE (JAXB annotated 
    POJOs),  as opposed to point integrations for JAXB/JPA/POJO/etc. 
    
No SDO POJO annotations required.  Instead the integration point 
    between JAXB/Java EE and SDO is the XML schema. 
    
SDO becomes a value add to JAXB/Java EE introducing enriched metadata, 
    relationship management, dynamic APIs, change summary, etc. 
    
No changes are required to existing Java EE applications (that already 
    expose data as XML) to make them compatible with SDO.  This is what our 
    customers want, a mechanism to make their existing Java EE applications 
    compatible with SDO enabled middle-ware 
  plumbing.

-Blaise

Barack, Ron wrote: 
  
    
    
Hi Blaise,

    
 

    
Lots of interesting stuff.  In a way, the proposal 
    is not far from the "project/cast" methods I proposed here:  http://www.oasis-open.org/apps/org/workgroup/sdo/download.php/27905/SDO3%20Java%20Projections.ppt.  
    See slides 29 and 30.  You've added JAXB intelligence.  Do you see 
    other special contexts, eg, JPAHelperContext or DomHelperContext?  If I 
    understand you, you'd be against anything like a PlainPojoHelperContext, 
    right?

    
 

    
Over the year, I've personally become less convinced of 
    the wrapping approach, as opposed to providing some kind of optimized data 
    transfer. What do you see as the advantage of wrapping over some kind of 
    convert operation?  Instead of wrapping the POJOs, I could mashal them 
    in JAXB, and load them using XMLHelper.  Does wrapping give me 
    something here I could not get through such a mechanism (modulus 
    performance)?   And of course because of the second point below, 
    the getters and setters could become significantly more expensive, 
    offsetting the gains made in avoiding a conversion step.

    
 

    
There is a third approach, and that is for the 
    framework to weave the POJO classes, so that "new Customer()", or at least 
    ObjectFactory.createCustomer() returns an object that already implements 
    DataObject.  It seems to me this is a straightforward extension of JPAs 
    approach.  In our JPA integration, you turn on this bytecode 
    enhancement with a flag in persistence.xml.  Do you think it would be 
    possible to get to this level of integration with JAXB?

    
 

    
Either way, I have some questions to the 
    details:

    
 

    
Why is the call to XSDHelper.define() necessary?  
    Couldn't the metadata be introspected from the POJOs (ala 
    generateSchema())?  Isn't there a danger of the XSD being out of sync 
    with the classes (similar to your comment regarding the @schemaLoc 
    annotation?

    
 

    
Does  DataObject customerDO = hc.wrap(customer); 
    always return the same DataObject?  It's maybe a implementation 
    detail, but does wrap create the DataObjects lazilly or all at 
    once?  If you do it lazilly, you 
    need to 
    maintain a map from the POJO object to the DataObject wrapper, right?  
    Otherwise as we navigate around, we could wind up with the same POJO having 
    2 DataObject wrappers.  And such a map raises a bunch of ugly lifecycle 
    issues.  This is where I thought something like a binder could come 
    come in handy, as a way of putting the lifecycle in the hands of the 
    client.  

    
 

    

    
What happens if a wrapped POJO is modified?  
    Obviously, calls to DataObject.get() would see the changes, but what about 
    things like change tracking, containers, and bi-directional properties, 
    that, in SDO happen implicitly when a setter is called?  Are you 
    "weaving" the byte code of the JAXB POJO?

    
 

    
Is there any way to start with a DataObject, and 
    generate a JAXB from it?  Ie, can I unwrap something that hasn't been 
    wrapped?  When I create a DataObject using DataFactory.create(), does 
    it automatically create an underlying POJO?

    
 

    
Regarding the StAX and JAXB dependencies.  
    I guess it will be 2010 before any SDO 3 implementations are released 
    as products...  I imagine by that time pretty much everyone will be on 
    JSE 6.  Maybe we should consider raising the minimum compatible JSE to 
    JSE 6.  What do you think?

    
 

    
You mention that 
    customers have expections about the XML representation of POJOs.  What 
    about POJOs that are not organized into a containment structure?  Eg, 
    my example:

    
 

    
    class 
    School {

    
        
    List<Student> getStudents() {...}

    
        
    List<Course> getCourse() {...}

    
     
    }

    
     
    class Course {

    
           
    School getSchool() {...}

    
           List<Student> 
    getStudents() {...}

    
      }

    
      class Student 
    {

    
           
    School getSchool() {...}

    
           
    List<Course> getCourses() {..}

    
      
    }

    
 

    
what do your customers 
    expect from the XML representation of School?  AFAIK, the programmer 
    has to specify the XML containment structure as part of the model, He must 
    annotate give the object ID properties, and he must use @XmlID to indicate 
    non-containment.  I don't think SDO is competing with JAXB if it 
    specifies a mechanism through which such graphs can be marshalled to 
    XML.  SDO 3 offers 2 such mechanisms:  the graph could be placed 
    inside an container with orphan properties, and the containment structure 
    (or alternate structures) can be imposed on the model through the project 
    method.  Offering this kind of fuctionality is one reason to include an 
    SDO-POJO binding in SDO 3.

    
 

    
 

    
 

    
Best 
    Regards,

    
Ron

    
 

    
 

    
 

    

    

    
    Von: Blaise Doughan [mailto:] 
    
Gesendet: Freitag, 23. Januar 2009 17:02
An: Barack, 
    Ron
Cc: 
Betreff: Re: 
    [sdo] ISSUE 5 and ISSUE 22: Discussion of JAXB

Hi 
    Ron,

I'm glad you raised this email thread.  Integration with 
    JAXB (POJOs) is also an important use case to Oracle and in particular the 
    EclipseLink SDO implementation.

Both SDO and JAXB have an XML schema 
    representation of their metadata.  For us this is the join point 
    between these two technologies.  EclipseLink DataObjects are capable of 
    wrapping POJOs, actions applied to the DataObjects (set/unset/detach/etc.) 
    are automatically applied to the underlying POJO.  I have included some 
    code below to demonstrate:
 
    // JAXB - Create 
    the JAXB Context
    JAXBContext jaxbContext = 
    JAXBContext.newInstance("com.example.customer");
 
    
    // SDO - Create the JAXB aware HelperContext
    
    HelperContext hc = new JAXBHelperConext(jaxbContext);
    
    hc.getXSDHelper().define(customerXSD);
 
    // 
    SDO - Wrap the POJO in a DataObject
    Customer customer 
    = new Customer();
    
    customer.setLastName("Doe");
    DataObject customerDO = 
    hc.wrap(customer);

    // SDO - Create and modify 
    DataObjects
    
    customerDO.getString("last-name");   // returns 
    "Doe"
    customerDO.setString("first-name", 
    "Jane");
    DataObject addressDO 
    customerDO.create("address");
    
    addressDO.setString("street", "123 Any 
    Street");
 
    // SDO - Unwrap the 
    POJOs
    // Note: customer == 
    hc.unwrap(customerDO)
    Customer customer2 = (Customer) 
    hc.unwrap(customerDO);
    
I would prefer to not 
    invent a POJO to SDO binding.  Our customers have expectations about 
    the XML representation of POJOs.  As JAXB is included in Java SE 6, I 
    imagine many people share these expectations.  If Java objects save to 
    XML one way, the act of wrapping them in (or converting them to) DataObjects 
    should not change the XML representation.  Of course if users choose to 
    make use of concepts such as ChangeSummary then the XML representation 
    begins to diverge but in predictable and explainable ways.  For us it 
    is imperative that SDO provides a compatible value add to Java EE, and not 
    become a competitor to any of its technologies.

Other Points:

    
      
I agree JAXB annotations do not contain enough metadata to reproduce 
      all SDO metadata.  For example JAXB cannot represent the property 
      index of attribute properties. 
      
JAXB classes generated from XML schema can contain properties that are 
      different from SDO class generation.  Especially wrt choices and 
      substitution groups. 
      
JAXB is primarily concerned with Java classes, while SDO is concerned 
      with Java interfaces.

      
More load/save targets (such as StAX) would be great.  Of course 
      StAX is not included with Java SE 5, and would introduce a new dependency 
      jar.  JAXB has this same requirement and goes away with Java SE 6, so 
      this may not be a big concern. 
      
The JAXB Binder maintains a link between POJOs and DOM nodes.  
      Once linked you can make changes on one side and then make an explicit 
      call (it doesn't happen automatically) to apply the changes to the other 
      side.  While useful the default JAXB algorithm isn't always what 
      users expect.  Our implementation provides the user with the choice 
      of 3 different "binding" algorithms. 
-Blaise

Barack, Ron 
    wrote: 
    
      
      
Hi Everyone, 

      
The idea of using JAXB annotations as a 
      solution to ISSUE 22, even of consolidating static SDO and JAXB, has come 
      up repeatedly in the calls.  I think we may be able to make better 
      progress in this regard by discussing the ideas per email, so that there 
      is a permament record of the arguments.  Having this discussion now 
      will hopefully make the discussion during the F2F more 
      productive.

      
First I want to say that integration with JAXB 
      is a high priority issue for us, but this integration may take several 
      forms:

      
1.  Transfering data between the 
      representations 
2.  JAXB 
      annotations as a source of SDO metadata 
3.  JAXB classes as static SDOs 

      
Of course, it is desireable to have as deep and 
      integration as possible.  When I first started thinking about the 
      problem, I set out to achieve all three types of integration.  After 
      long consideration, I arrived at the conclusion that only the first is 
      really possible.

      
About the first point I hope there is general 
      agreement: Applications that use SDO as a data representation must be able 
      to transfer data with applications that use JAXB. In some ways, this is 
      already possible in 2.1:  all you need to do is mashall to XML. This 
      approach introduces some performance costs, and I think we should address 
      steamlining the process in SDO 3.  One approach that we've found to 
      be very helpful is for SDO to be able to produce an XMLStreamReader which 
      in turn can be fed into a JAXB marshaller.  For maintaining an active 
      map between the representations, I believe a DOMBinder is a very promising 
      approach, and possibly we could go a step further and have a JAXB 
      binder.  (Unfortunately, I believe the JSE implementation of JAXB 
      still has an incomplete version of the DOMBinder 
functionality).

      
Similarly, clients can already use JAXB 
      annotations as a source of SDO metadata under SDO 2.1, at least whereever 
      JAXBContext.generateSchema works it is possible to use XSD as an 
      intermediate metadata format. However, it is important to realize that 
      JAXB does not provide the level of details we expect to see in a 
      resolution to ISSUE 22.  JAXB annotations capture exactly the 
      information necessary to correctly marshal and unmarshal to XML.  
      Restrictions (facets), and all reference to the original simple type is 
      lost.  JAXB creates String properties for xs:NCName, xs:AnyURI, etc., 
      and there is no way to get back to the original type through reflection on 
      the JAXB object.

      
JAXB objects reflect the purpose of JAXB, which 
      is to create an XML binding for Java.  XML models, and therefore 
      JAXB, do not contain (as a rule) bi-directional or non-containment 
      references.  It's true that XML and JAX can represent non-containment 
      relationships using @XmlID, but in SDO non-containment relationships are 
      not limited to objects that have ID properties (or even keys).

      
If we were to use JAXB annotations as the 
      standard way to represent SDO metadata in Java, then we are also accepting 
      the default behaviour associated with the *absence* of these 
      annotations.  In JAXB, an unannotated POJO class that references a 
      second POJO class is intepreted as there being a containment relationship 
      between the associated types.  I would argue that this should not be 
      the default behaviour for SDO.  If it were, then we loose the ability 
      to to take an arbitrary model based on unannotated classes, pack them in a 
      DataGraph (or anything else that has an orphan property) and being able to 
      generate XML for the model.  The assumption of containment 
      relationships means that we will get cycles and other problems, making the 
      whole approach unworkable.

      
A further problem is that I think we would 
      probably be misusing the JAXB annotations.  Static SDOs may be 
      interfaces or generated classes.  JAXBs are annotated POJOs 
      (JavaBeans).

      
Finally, very pragmatically, the JAXB spec is 
      large and complex.  Expecting implementations to make sense of the 
      annotations and their many combinations is a very high bar indeed, even 
      more so when we expect to enrich the annotation set with some of our own 
      annotations.

      
Having rejected the second point, perhaps the 
      discussion of the third point is moot, but I want to discuss it because 
      the appeal of the approach is so strong.  The appeal can be 
      summarized as follows:  "The JSE already defines a standard XML to 
      Java binding.  By defining static SDOs, we are defining a competive 
      functionality that is therefore doomed to be rejected by the java 
      community.  The problem with this argument is that static SDOs do not 
      represent an XSD, they represent SDO metadata.  Although a large part 
      of the SDO spec contains the mapping between the metamodels, the models 
      are not the same, not is the SDO metamodel a subset of the XSD metamodel 
      (multiple inheritence, bi-directional relationships being two examples of 
      constructs that do not exist in XSD).

      
On a more practical level, although for very 
      simple XSDs the classes generated by JAXB and the static SDOs defined in 
      SDO 2.1 are compatible, we very quickly come to places where the models 
      diverge.  SDO represents choices as several parallel properties, and 
      we expect the user to fill one or the other.  JAXB generates a sort 
      of combined property (using the pattern "getAorB"), and the user must 
      create an JAXBElement and use this value to set the property.  It 
      would be very odd to have this structure reflected in the static SDO when 
      it is missing from the SDO metamodel.  In cases such as those where 
      we create a sequenced DataObject, JAXB creates an class with a single 
      getContent() method.  Static SDOs, like SDO itself, maintains in such 
      cases a property oriented view of the data in addition to the sequenced 
      view.

      
I hope this gets the discussion going so that 
      we can decide what sort of integration with JAXB we are aiming for, 
      whether or not we we need to define our own annotations, etc.  
      Blaise, as a member of the JAXB EG, I'm particularly interested in your 
      comments.

      
Best Regards, 
Ron
← Prev in month ← Prev in thread
Next in thread → Next in month →