Thursday, July 11, 2013

Using GWT and Hibernate (JPA)

This article discusses an option to use Hibernate and JPA entities directly in a GWT application. It uses a small project JpaCloner which can be found on the github https://github.com/nociar/jpa-cloner. The Google Web Toolkit  framework itself declares support for JPA entities. It means that the GWT is able to:
  • Translate JPA entities to Javascript.
  • Serialize JPA entities in GWT-RPC calls.
So there should be no problem to use your JPA domain model direcly in the client code (as JPA entities are translatable). But just try to return a JPA entity from your GWT-RPC calls. The call will end with a SerializationException. There are two problems related to the serialization of Hibernate entities by GWT. Both problems are discussed in following paragraphs.

Javassist proxies

The first probem of the serialization is caused by the type of Hibernate entities. Hibernate uses javassist proxy classes which are not known to the GWT during the compilation time. GWT is also not able to serialize lazy collections implemented by Hibernate. So the declared support of JPA by GWT seems to be useless when using Hibernate. But the situation is not as bad as it seems. :-) The thing to be done is very simple - just replace the hibernate proxies by raw JPA classes and lazy collection by standard java.util collections. The good news is that you are not forced to do it manually. You can use a small project JpaCloner for all of this, the usage is extremely simple, for example:

/** Return an instance of Company by ID. */
public void Company getCompany(long id) {
    Company entity = entityDAO.getEntity(id);
    return JpaCloner.clone(entity);
}

Please note that the JpaCloner creates a cloned entity of the raw JPA class - this means that you can easily get rid of Hibernate proxy classes.

Serialization depth

The second problem of the serialization is related to ORM technologies in general. There must be somehow defined an object graph which should be serialized. GWT-RPC serializes all properties of a returned object . In case of bidirectional JPA mappings it would easily serialize the whole DB which is of course not acceptable. Only a subset of neighboring entities should be serialized (entity subgraph). This can be again accomplished by the JpaCloner's clone() methods. Additional parameters can specify property paths and the depth of cloning. The following example shows how to serialize a company with a hierarchical department structure:

/** 
 * Return an instance of Company by ID. The instance 
 * will contain also all departments and employees.
 */
public void Company getCompanyWithDepartments(long id) {
    Company entity = entityDAO.getEntity(id);
    return JpaCloner.clone(entity, "department+.employees");
}

Please note that the cloning should be done in a transaction scope to prevent lazy initialization exception thrown by Hibernate. 

Conclusion

So what to say at the end? Just that the usage of JPA entities in your GWT projects can be easy and straightforward. There is no need to use sophisticated frameworks, nor to use redundant DTOs and Dozer which mostly mirror related JPA entities. The JpaCloner does not have any dependencies and is completely non-invasive. This is not true for projects like hibernate4gwt (now Gilead) which forces you to extend your domain model entities from the LightEntity class.

Happy coding :-)

Monday, April 15, 2013

Cloning of entity subgraphs

First of all, I have to introduce myself. I work as a programmer, analyst and a SW architect since 2003. Past experiences with JPA and Hibernate motivated me to write this short article about considerable benefits of entity cloning. I also introduce an opensource project JpaCloner. You can find it on the github link https://github.com/nociar/jpa-cloner (released under the Apache License, Version 2.0).

Deep entity clone

The cloning mechanism itself is nothing new or special. Every semi-skilled programmer knows it (copy constructor in C++ or clone() method in Java). The cloning of a simple object is common and definitely not interesting for most of us. Until... we have to deal with concepts like fetching of entity subgraphs, defensive copying or the entity serialization. It is advisable in many situations to use, pass or return a deep copy of an entity. But the question is: how to define the deep copy? It depends on many factors but mostly on the actual context and requirements. So to be more precise, we often need to clone an entity subgraph. Deep copies of entities have many benefits, some examples:

  • A deep copy can be considered as a fetched entity subgraph.
  • A copy is always detached from a persistence manager. Any change of a copy does not affect the original.
  • A deep copy can be used out of a transaction scope and prevents the throwing of the LazyInitializationException.
  • A copy allows to get rid of JPA proxy classes. A proxy free copy can be serialized by many frameworks (like GWT RPC).

I found couple of projects which deal with similar concepts like Apache Dozer, Gilead (hibernate4gwt) or JpaEntityManager#copy() in EclipseLink. But non of them fulfills my needs, so I decided to do a small project myself. Following sections describe usage of the project in more details.

Entity subgraph

JPA/ORM mapping can be considered as a graph of POJOs. Entities are nodes and relations are edges (singular, collection or map). A deep clone of an entity should also make deep clones of neighboring entities and their neighboring entities, and so on... Such strategy of transitive cloning may easily ends with the whole DB cloned and OutOfMemoryError thrown. We have to clone only a part of the object graph - subgraph. The desired subgraph can be specified by a set of paths from a root entity. After some time I found that the common dot notation (e.g. "company.department.boss.address") is not flexible enough to cover many additional needs like recursive relations and path splitting and joining. So I introduced the GraphExplorer class which generates the paths upon a string pattern. String literals inside the pattern are treated as properties. Operators resemble the syntax of regular expressions:
  • Dot "." separates paths.
  • Plus "+" generates at least one preceding path.
  • Split "|" divides the path into two ways.
  • Terminator "$" ends the preceding path.
  • Parentheses "(", ")" groups the paths.
  • String literals support wildcards: star "*" and question mark "?".
Some examples follow:
  • project.devices.interfaces
  • project.devices.inter??ces
  • project.devices.*
  • school.teachers.lessonToPupils.(key.class|value.parents)
  • company.departments+.(boss|employees).address.(country|city|street)

JPA Cloner

The JpaCloner class allows to clone entity subgraphs specified by the string patterns. After the algorithm is finished, each cloned entity contains basic properties (columns) and cloned relations. Non-cloned relations are left as null. The cloned entities are always created as raw classes (annotated by the @Entity or @Embeddable). So a cloned object will never be a hibernate proxy. The JpaCloner supports relations defined as List, Set, SortedSet, Map and SortedMap. The class contains static methods to shield the programmer from the implementation details. The usage looks like:

MyEntity e = em.find(MyEntity.class, 1234);
MyEntity c = JpaCloner.clone(e, "x.y.z", "aa.(bb.cc)*.dd");

If you need to clone a list or a set of entities, you can use overloaded clone methods:

TypedQuery<MyEntity> query = entityManager.createNamedQuery(...);
List<MyEntity> list = query.getResultList();
list = JpaCloner.clone(list, "x.y.z", "aa.(bb.cc)*.dd");


Conslusion

Working with JPA and ORM may easily become painful (and in some cases a nightmare). This applies especially when it comes to a persisting and merging of complex structures with higher-level semantics. I found that using clones makes my work with ORM again entertaining. Clones can be returned by any transactional method with fetched subgraphs (I use it in my GWT applications). I hope that the project will be useful not only for me :-)