Showing posts with label jpa. Show all posts
Showing posts with label jpa. Show all posts

Friday, July 16, 2010

Dream is not reality

Well I tried to build a web service returning a JFrame... isn't that the cool thing about Java reflexion / serialization.....


SEVERE: Cannot initialize endpoint  : error is :
javax.xml.ws.WebServiceException: Unable to create JAXBContext


Blah blah

Caused by: java.security.PrivilegedActionException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 21 counts of IllegalAnnotationExceptions
java.awt.LayoutManager is an interface, and JAXB can't handle interfaces.

Well the least I can say, making Swing and Server based Java is not always simple...

Thursday, July 15, 2010

My solution to the XmlID XmlIDREF and the object graph reconstruction

At the previous stage, I stopped with a situation where I could  get an entity (a patient) but nothing about a related entity (a doctor). The reason being that to break the serialization loop I used the XmldID and XmlIDREF annotations.


In the soap response I can see the doctor id (2). In Java the doctor field of the patient points to null (because as shown in the previous post, the doctor is not transfered).

By the way in Open ERP I would get not the doctor but at least the in id in the Python object. One more shame on Oracle/Sun stuff.

Anyway, I created another web service that does not return a single patient record but a compound of entities (a collection of patients and doctors) :

public class wsbr {
    private Collection patientCollection;
    private Collection doctorCollection;
    public Collection getPatientCollection() { return patientCollection ;};
    public void setPatientCollection(Collection p ) {  patientCollection = p;};

    public Collection getDoctorCollection() { return doctorCollection ;};
    public void setDoctorCollection(Collection p ) {  doctorCollection = p;};

   
}


Building a web service that returns such object and populating properly the two collection makes possible to transfer the entire graph which is rebuilt properly at the client side (automatically).

Here is the soap :



So my solution is to build a big compound referencing object that will ensure that all references will be carried properly.

Wednesday, July 14, 2010

JPA, JAXB ... not finished yet

I could indeed load one entity... but

Here is my result

   
     
Clearly the actor is not passed in the response and so my graph of object is not passed...


Here is the thing I overlooked... https://jaxb.dev.java.net/guide/Mapping_cyclic_references_to_XML.html

"There are a few things to consider when you do this. First, the object to be referenced must have an ID that is unique within the whole document. You'd also need to ensure that the referenced objects are contained somewhere else (like in the Root class in this case), or else Bar objects will never be marshalled. This technique can be used to remove the cyclic references, but it's only possible when your object model has an easy cut point."


So...

GlassFish - JPA & Jaxb

So I am preparing a major rewriting of our last Major App in Delphi. The client side will be in Java - we need at least one Java component for text manipulation. I will come back later on the client as I looked at a lot of nice stuff.

One the server side things are also difficult. My intention is to go to JPA as it is now the standard ORM and will give us portability between DB and probably also a much cleaner code.

The JPA classes were created automatically by Netbeans. Next I created a stateless session bean and finally a Soap Web service (Netbeans created that one from the session bean). It is a lot of artifact... A good thing again, I suppose done by Netbeans, your web service also generate a small web base tester for the service.

Unfortunately I hitted the first issue yesterday...

Caused by: javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML: com.adins.testNISFusion.jpa.Patient[id=1] -> com.adins.testNISFusion.jpa.Actor[id=1] -> com.adins.testNISFusion.jpa.Patient[id=1]]
        at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:269)
        at com.sun.xml.bind.v2.runtime.BridgeImpl.marshal(BridgeImpl.java:110)
        at com.sun.xml.bind.api.Bridge.marshal(Bridge.java:178)
        at com.sun.xml.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.java:297)
        ... 56 more


So the session bean works fine but the web service cannot serialize the answer properly because there is a loop in the references (which by the way is the most common things you get in a relational database and these references have been created by Netbeans/JPA).


The solutions are listed here ...

https://jaxb.dev.java.net/guide/Mapping_cyclic_references_to_XML.html

The first one is to make the referenced entity XmlTransient  so basically not referenced any more. It is difficult for me to see this as a solution. May be if your DB is made of non used entities...

The second is to use XMLID and XMLIDREF directive. So instead of serializing recursively JAXB will point to the ID of the other entity.

In my case - I think a common one. The entity being passed through the web service are in fact my JPA entities. So your JPA entitiy gets fields annotated with@ID and @XmlID.

Unfortunately combining JPA and JAXB   creates another issue.

Caused by: java.security.PrivilegedActionException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "id"

Strange...

I foud a solution here : http://www.objectpartners.com/2010/01/25/using-jpa-and-jaxb-annotations-in-the-same-object/

Basically, you will put the JAXB annotation on the accessor not on the variable where you put the JPA ones.


So something like :

....

@XmlRootElement
public class Patient implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)

....
@XmlID
    public String getId() {
        return id;
    }


Conclusion at this time...
1) It works for now.
2) Netbeans is great and generates plenty of stuff that I will have to modify by hands... :-(
3) JPA stuff is very static but JAXB builds XML at runtime. So you get the worst combination : modification requires compiling and compiling does not shield you from syntax error...
4) I don't like that much annotation. The syntax is ugly. In the case of the transient 'solution', it is hard to imagine that you can solve all the real cases statically. Sometines you need the element, sometines not...
5) A stack is just a stack of boxes as drawn on the marketing docs. It seems little people spend time to make these boxes working really together.  
6) I have been trough a lot of readings, an entire stack of books... Building a web service to pass persistent entity is just basic and yet nobody mentions this issue...This is in my opinion the key drama of this industry. Book writers (as tools builder) rarely  build appications,...
7) It would be great to have a single option for JAXB to tell that we want to use ID and REF...Who knows...

Friday, January 08, 2010

Some JPA for a tiny library management app

I am part of the parents comittee of my kids school. Among our projects we are trying to setup a small library for kids.

I like helping the community but  these projects are challenging because we run on a nearly zero € budget.

So I proposed myself to manage the book catalog. I built a year ago a small Java app for printing stickers with barcode (an opportunity for doing raw printing). Now I am working on the application to mange book leases.

I took this opportunity to use JPA for building a Swing desktop application. The databasee has been designed directly with MySQL. I imported the schema and Netbeans (6.8) generated the persistene unit and the Java classes. Good but the generation was a bit disappointing. Foreign keys (many to one) were not implemented as reference to Java objects, so I had to code this myself.

What I like with JPA is the feeling to be isolated from the DB specificities without being tight to one JPA provider. I switched just to try from Hibernate to TopLink to EclipseLink, it works great.

Building Java Swing application is rumored to be a pain. With Netbeans it is relatively confortable.... You can drag and drop components on forms as you do with Delphi or VB.

The interface builder is doing something very nice. By looking at how you position components it deduces rules you would like to see respected. Nice, things get properly aligned and are well adaptative when you expand windows. Conceptually that's perfect.

Yesterday, I was almost finished with the app, being able to lease out and log book returns... Unfortunately I tried to fix a couple of glitch in the status bar of the app. What I did? Don't know. The net result is that after three hours of work last night, my entire layout collapsed and the app is basically unusable at this stage...