Felipe Gaúcho works as senior software engineer at Netcetera AG in Switzerland. He is a well known Brazilian JUG leader and open-source evangelist. Felipe works with Java since its early versions and has plans to keep that Java tradition as it is. When he is not coding, he prefers to listen reggae and travel around with his lovely wife Alena and his son Rodrigo. Felipe is a DZone MVB and is not an employee of DZone and has posted 29 posts at DZone. View Full User Profile

Question: How to bind SOAP <-> ORM JPA ?

09.04.2008
| 5110 views |
  • submit to reddit

After a few days of evaluating my options about binding my SOAP message objects to my JPA entities... I have:

A soap serializable type, let's say SoapType:
package soap.objects;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"number",})
@XmlRootElement(name = "Domain")
class SoapType implements Serializable {
@XmlElement(name = "entity.id")
protected long entityId;
public long getEntityId() { return entityId; }
public void setEntityId(long value) { this.entityId = value; }

@XmlElement(required = true)
protected String uri;
public String getUri() { return uri; }
public void setUri(String value) { this.uri = value; }

// ....other.fields.and.methods.here...
}

A JPA entity type, let's say SoapEntity:

package jpa.objects;

@Entity
@Table(name = "SOAP_TYPE")
public class SoapEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
protected long id;
public long getId() { return id; }
public long setId(long id) { this.id = id; }

@Column(name = "URI", nullable = false, unique = true)
protected String uri;
public String getUri() { return uri; }
public String setUri(String uri) { this.uri = uri; }

// ....other.fields.and.methods.here...
}

As you can deduct from the short code samples, every time my web-service receives a SOAP message containing values that should be persistent in the database, I should convert the received objects to the JPA entities. And every time I read the data base to respond a service request, I should convert the read entity in the respective object that can be serialized in the SOAP messages. A dual channel repetitive copy mechanism - a copy layer - or binding framework. I don't like the term binding since the objects not only differs in format but the objects are part of completely different models - this is another topic I prefer to skip here.

Question: How to copy the values between the SOAP Message elements and the JPA entities?

Options I am considering right now:

  1. Brute force, copying one by one the fields and properties from one side to another. Simple, fast and the most reliable solution, but with a lot of identical code for all entities. The number of line codes required to copy is linearly coupled with the number of entities and their attributes (can be thousands of lines to code and maintain).
  2. Recursive Reflection: trying to match the getters and setters names.. it works fine for shallow copy but becomes weird with collections and nested complex types. Reflection reduces the number of lines and, depending on the simplicity of the models, can be a good option. You pay a bit of performance but in my early experiments, the cost/benefit of reflection is good. Dozer is a nice option here but it imposes quite a lot of dependencies and seems Spring oriented - so, if you are using Spring, go for it.
  3. Adapters using annotations: similar to the solution proposed here, but instead of mapping XML to Objects I plan to map different objects (from different models).
  4. Inheritance between the soap objects and entities: entities are declared subclasses of XML generated objects, so I need to copy only from xml to entites, the reverse order is naturally bounded by casting. What means you solve half of the problem :). This points to an unwanted coupling between the models, but reduce the processing effort, so the bargain between the beauty and the power is up to you.

I certainly will blog here if I find a good workaround to this problem, so I hope to hear from you something new. :)

From http://weblogs.java.net/blog/felipegaucho/

Published at DZone with permission of Felipe Gaúcho, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Manjuka Soysa replied on Thu, 2008/09/04 - 10:38am

Hey Felipe.. I think this was discussed a few times, the latest being here:

http://soa.dzone.com/articles/service-orientation-vs-object-

 

In my opinion it is a gap in JEE, there is no clean solution. I keep thinking SCA might have a solution, but haven't got around to studying it in detail :-)

My approach would be mapping, but not using brute force, but some tool like BeanMapper. 

Good luck! 

John J. Franey replied on Thu, 2008/09/04 - 11:49am

This is certainly a question from my ignorance: Why cannot there be a single classs with both sets of annotation?  This would be nice: one class for a business object useful in both JPA and WS framework, instead of a different class with a requirement to map data.

package business.objects;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"number",})
@XmlRootElement(name = "Domain")
@Entity
@Table(name="SOAP_TYPE")
class SoapType implements Serializable {
@XmlElement(name = "entity.id")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
protected long entityId;
public long getEntityId() { return entityId; }
public void setEntityId(long value) { this.entityId = value; }

@XmlElement(required = true)
@Column(name = "URI", nullable = false, unique = true)
protected String uri;
public String getUri() { return uri; }
public void setUri(String value) { this.uri = value; }

// ....other.fields.and.methods.here...

 

Raveman Ravemanus replied on Fri, 2008/09/05 - 7:32am

ROTFL, i thought they will hit you with some weird argument like DS should not store Xml logic or something like that, but from what i see they just didnt think about it. i see no reason why this should not work.

Manjuka Soysa replied on Fri, 2008/09/05 - 8:35am in response to: Raveman Ravemanus

Oh please, been there done that. The reason I didn't reply is that I posted a link to a previous thread which already answered that.

You can have different operations that return different object graphs (serialized to XML) involving the same class. So having one representation as annotations is not a great solution. 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.