Handling frequent schema change in the jaxb - java

In my application we are using JAXB for unmarshalling incoming xml response.
JAXB pojos are further mapped to DAOs for DB operations.
My issue is our service provider is going to frequently update their schema(xsd)(insertion, deletion of elements and attributes) and i dont want to keep generating POJOs for different versions of the same schema and updating my other codes.
Please suggest a solution to handle this scenario.

You may want to look into MOXy's Dynamic JAXB feature. It allows you to bootstrap a JAXBContext directly from the schema, and interact with your model objects in a dynamic, schema-centric way. Using this approach your application code would need to be updated to work with any new schema elements, but your JAXB binding code would stay the same.
Please see: http://www.eclipse.org/eclipselink/documentation/2.4/moxy/dynamic_jaxb.htm#sthref191
Hope this helps,
Rick

Related

Convert XML to database with Java

Need: take in XML and save data to database.
Currently using: JAXB to convert the XML Schema to java classes. Then I intend to use JPA to persist the objects marshalled by JAXB.
Problem: I want something to bridge the gap. After JAXB generates the Java classes I have to manually annotate all java.util.Date fields with #Temporal; I have to put #Entity on the top of every generated class...etc.
I came across Hyperjaxb. But I can find little documentation on it, and can't get it to work.
I am open to completely different approaches. This seems like it would be a common problem, so maybe there is a generic solution.
Note: I'm the EclipseLink JAXB (MOXy) lead, and a member of the JAXB 2 (JSR-222) expert group.
If you already have an existing database schema, the you could use the Dali tool in Eclipse (part of the Web Tools Project) to generate your JPA entities form the database:
http://www.eclipse.org/webtools/dali/
JAXB is configuration by exception, this means you only need to add annotations where you want to override the default behaviour. Dali also has tooling to make adding JAXB annotations easier:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/TheBasics
JPA entities sometimes use bidirectional relationships and composite keys, these can be tricky to map to XML. EclipseLink JAXB (MOXy) contains some extensions to make this easier (note EclipseLink also offers a JPA implementation):
http://blog.bdoughan.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
Hyperjaxb does exactly what you're trying to achieve. Here's the documentation:
http://confluence.highsource.org/display/HJ3/Home
Here's a tutorial to get you started:
http://confluence.highsource.org/display/HJ3/Purchase+Order+Tutorial
I can suggest two options:
Option 1. Define your entity types separately, having the relevant JPA annotations, generate your JAXB types from the schema, and at runtime, map one to the other. If it is a simple mapping you can use Apache BeanUtils to just copy over the attributes from one bean to the other, if it is a more complex mapping then you can use a framework like dozer
Option 2: Start from entity types, generate the schema from your entity types or manually keep the entity types and the schema in synch. More like the option that you have described, except that the authoritative source is the java code than the schema.

JAXb, Hibernate and beans

Currently I am working on a project with Spring web-service, hibernate and JAXb.
1) I have generated hibernate beans using IDE 'hibernate code generation,
2) also, I have generated the jaxb beans using maven compiler.
..
Now, my question is,
1) Is this the right approach? (to have so many beans).
2) Shall I use JAXb beans for processing into the service layer? How can I keep layers decoupled?
3) Or, do I need to create another set of beans ie. map (JAXb beans) to (new beans) to (hibernate beans)?
.
Please tell your views?
Thanks,
adi
You know, you cannot have everything fully decoupled. There will be always a layer that will know the other two layers.
Usually when I design 3 layers architecture, like:
Service Layer - the one that probably uses JAXB, exposes web services or other APIs
Business Layer - any real logic
Persistence Layer - hibernate
I allow the Business layer to know about the Service Layer (JAXB) and about the Persistence Layer (hibernate beans). But I don't allow the Service Layer and the Persistence Layer to know about each other.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group. EclipseLink also provides an excellent JPA implementation (open sourced from TopLink).
There are costs to maintaining multiple models. Each model you add introduces a bean-to-bean conversion that must be written, tested, and maintained.
Another approach is to use the same beans for both the JPA and JAXB bindings. For this use case it will be easier to start with domain model and add JAXB & JPA metadata to apply mappings to XML and the database. Below is example of where a single model is leveraged to create a RESTful web service:
http://blog.bdoughan.com/2010/08/creating-restful-web-service-part-35.html
Since EclipseLink provides both JAXB and JPA implementations we provide a number of extensions to make this easier:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
http://blog.bdoughan.com/2010/07/jpa-entities-to-xml-bidirectional.html
UPDATE
In response to:
Agree to what you are saying. However, using same beans will couple
the code very tightly and will be highly dependent. Change in one
layer will need changes elsewhere as well. What you say?
It all depends how you look at things. My preference for building data access services is to design and build a solid domain model. Then use JPA and JAXB to solve the impedance mismatches between object-relational and object-XML.
One Model Approach
Using one model for both JPA and JAXB means that when you make a change to the model you need to decide at that time how it will be handled for both JPA and JAXB (this can be good or bad). If you don't want every new addition to the model to affect the JAXB mapping you can leverage JAXB concepts like #XmlAccessorType(XmlAccessType.NONE).
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
Two (or More) Models Approach
When you want to add a field that is mapped to both relational and XML you need to add it to two models and add the necessary conversion logic. In this case there is a cost to keeping the models de-coupled.

Is it possible to auto generate annotated-mapped POJO classes using techniques like Hibernate, JIBX etc?

Hibernate can auto-generate schemas from properly annotated POJO classes. And I also know that JIBX can create a data model (set of classes) out of properly structured XML schemas. Is there a way to automaticaly generate annotated-mapped classes from an XML schema? Or is it just possible to run a tool on a set of POJO classes, and expect it to create meaningful annotations on the specified classes? So later on we can create database schemas using these classes. To annotate every class that JIBX produces takes actually more work than manually designing the database schema according to the xml schema.
The Hyperjaxb project will generate JAXB classes from an XML schema that contain JPA annotations that could be used to create a database schema.
http://java.net/projects/hyperjaxb
Nice question! We had the same problem and we ended up developing the POJO generator with Freemarker.
By the way, the requirements to these POJOs may strongly vary, so, if such tool exists, it must have quite bloated configuration.

Which web service stack allows binding wsdl first web service to existing classes in Java?

Greetings,
I have a complicated scenario to handle. I have a wsdl file which uses a particular XML schema.
The XML schema is actually a handcrafted implementation of a specification. There is also a Java based implementation of the same specification. So the XSD used in WSDL and Java classes at hand are quite similar, but not exactly same.
Almost all web service stacks allow creating classes from WSDL or creating WSDL from Java class annotations.
What I want to do, is to use the WSDL and bind XSD used in the wsdl to existing java classes.
Should/can I do this by manually replacing generated Java classes with existing ones? Is it a matter of changing type names in config files and moving binding annotations to existing classes?
If you know any best practices, or java web service stacks that support this kind if flexibility in a practical way, your response would be much appreciated.
Best Regards
Seref
I suggest Spring's Web Services module, which has no code generation involved, but provides a clean separation of concerns. Different concerns are broken out nicely by allowing you to provide your WSDL and existing schema(s) on one side (contract first), your existing Java-based domain model on the other, and a way to plugin in your OXM (Object-XML Mapping) technology of choice.
Since you have hand-crafted WSDL/schema and hand-crafted Java classes, the real work will be in configuring your OXM. I prefer JiBX as it keeps the concerns separated (no XML annotation garbage mixed into your domain) with JAXB as a backup if the learning curve looks too steep. Spring Web Services supports several other OXM frameworks, and you can even use several different ones at once.
As far as best-practices, I consider hand-crafted code a best practice, though I may be in the minority. If you generate classes from XML you end up with classes that are simple data containers with no behavior (assuming you want to regenerate them whenever your WSDL/XSD changes). This is bad if you favor the object-oriented paradigm because you end up having to place your "business logic" in utilities/helpers/services etc. instead of in the domain objects where it really belongs. This is one reason I favor JiBX. I can make very nice OO objects with behavior, a nice clean schema that doesn't necessarily match the objects, and can manage changes to either side with a mapping file similar to how hibernate does it for ORM (Object-Relational Mapping). You can do the same with JAXB, but that requires embedding XML structure into your object model, and binds a single XML representation to it (whereas with JiBX you can have many).
MOXY (I'm the tech lead) was designed for instances where you have an existing XML Schema and an exsting object model. It accomplishes this through XPath based mapping and can ever handle cases where the models are not that similar:
parse google geocode with xstream
MOXy also has an external binding file:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
MOXy is a JAXB implementation with extensions (A couple of which are mentioned above). IF you go ahead with Spring, MOXy is configured as a JAXB implementation, and you need to add a jaxb.properties file in with your model classes with the following entry:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Declarative XML -> POJO conversion

I have to write a process (in Java) which periodically hits a URL, reads the returned XML document, and persists that data into the DB. This data is further used by my application, so I have modeled them as Hibernate-mapped POJOs.
I can parse the XML and then create appropriate POJOs, but I was looking for a simpler declarative approach. What libraries are available which can take a input configuration and create the POJOs from the XML document?
Another alternative could be JiBX
Also, although you said you don't want to parse the XML, XPath can be a very concise way of extracting the content you are interested in?
JAXB can automatically create classes based on an XML Schema (assuming you have one for the XML source). At runtime, it can then convert the XML document into POJOs representing the XML. It is declarative in that you can tweak the Schema-to-class mapping, a little.
If I understand your task correctly, this is pretty much the use-case JAXB was designed for (though it can do other things too). It's part of Java 1.6 (maybe 1.5 too?), in packages: javax.xml.bind.*
You can use XStream to deserialize the XML and map it directly to the Hibernate-mapped POJOs.
Cheers.
Using Hibernate you can directly map XML to table. This is experimental feature. Check here
http://www.hibernate.org/hib_docs/v3/reference/en-US/html/xml.html
EclipseLink JAXB (MOXy) has extensions for mapping JPA entities to XML (JPA entities have things like embedded ID classes, lazy loading, and compound key relationships that need special handling), I'm not aware of any other OXM solution that does this.
For more information see:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA

Categories

Resources