piątek, 21 października 2011

Immutable value objects with Hibernate

Value objects are one the foundations of the Domain Driven Design. To take most of the benefits connected to them they should be immutable. This however causes some challenges when using them as an attributes of entities mapped using Hibernate.

Let's take a look at sample value object representing currency.

package com.acme;

public final class Currency implements Serializable {

 public static final Currency EUR = new Currency("EUR");  
 public static final Currency USD = new Currency("USD");  

 private final String code;
 
 public static Currency valueOf(String code) {
  if (EUR.getCode().equals(code) {
   return EUR;
  }
  if (USD.getCode().equals(code) {
   return EUR;
  }
  return new Currency(code);
 }

 private Currency(String code) {
  this.code = code;
 }
 
 public String getCode() {
  return code;
 }
 
 @Override
 public boolean equals(Object obj){
  if (!(obj instanceof Currency))
   return false;
  return code.equals(((Currency) obj).getCode()); 
 }
 
 @Override
 public int hashCode(){
  return code.hashCode();
 }
 
 @Override
 public String toString() {
  return code;
 }
}

Currency class is immutable which means that it is final, all of its fields are immutable and declared as final. Moreover it does not have any public constructor but instead it has a factory method which caches most commonly used values.

Now let's assume that we have an Order entity which has Currency as one of its attributes:

package com.acme;

import javax.persistence.Entity;

@Entity
public class Order {
 // ...
 private Currency currency;

 // ...
 public Currency getCurrency() {
  return currency;
 }

 public void setCurrency(Currency currency) {
  this.currency = currency;
 }
}

To map Order.currency attribute we need to create implementation of org.hibernate.usertype.UserType interface which will handle mapping of Currency class to VARCHAR database column.

package com.acme;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class CurrencyType extends AbstractImmutableType {
 
 public static final String TYPE = "com.acme.CurrencyType"; 

 private static final int[] SQL_TYPES = { 
    Types.VARCHAR 
 };
    
 public CurrencyType() {
  super();
 }

 public Object nullSafeGet(ResultSet rs, String[] names, 
    Object owner) throws SQLException {
  String value = rs.getString(names[0]);
  if (rs.wasNull()) {
   return null;
  }
  return Currency.valueOf(value);
 }

 public void nullSafeSet(PreparedStatement st, Object value, 
    int index) throws SQLException {
  if (value != null) { 
   st.setString(index, ((Currency)value).getCode());
  } else {
   st.setNull(index, SQL_TYPES[0]);
  }
 }

 public Class<?> returnedClass() {
  return Currency.class;
 }

 public int[] sqlTypes() {
  return SQL_TYPES;
 }
}

It uses AbstractImmutableType class which is defined as follows:

package com.acme;

import java.io.Serializable;

import org.hibernate.usertype.UserType;

public abstract class AbstractImmutableType 
  implements UserType {

 public AbstractImmutableType() {
  super();
 }

 public boolean isMutable() {
  return false;
 }
 
 public Serializable disassemble(Object value) {
  return (Serializable) value;
 }
 
 public Object assemble(Serializable cached, Object owner) {
  return cached;
 }

 public Object deepCopy(Object value) {
  return value;
 }

 public Object replace(Object original, Object target, 
   Object owner) {
  return original;
 }
 
 public boolean equals(Object x, Object y) {
  if (x != null && y != null) {
   return x.equals(y);
  }
  // Two nulls are equal as well
  return x == null && y == null;
 }

 public int hashCode(Object x) {
  if (x != null) {
   return x.hashCode();
  }
  return 0;
 }
}

To use CurrencyType we have to annotate Order.currency attribute with Hibernate's @Type annotation:

package com.acme;

import javax.persistence.Entity;

import org.hibernate.annotations.Type;

@Entity
public class Order {
 // ...
 private Currency currency;

 // ...
 @Type(type = CurrencyType.TYPE)
 public Currency getCurrency() {
  return currency;
 }

 public void setCurrency(Currency currency) {
  this.currency = currency;
 }
}

Mixins aka traits implementation in java

Mixins, also known as traits in some programming languages, are very useful language constructions. They cover most of the use cases where one's might want to use multi-inheritance but conceptually are much simpler. Unfortunately java does not support mixins. Nonetheless with some help from one of bytecode generation libraries like CGLib or javassit it is possible to implement simple mixins support in less then 100 lines of code.

The idea is to use java interface to define mixin methods. Additionally such interface should be marked with @Mixin annotation which will provide information about the class which implements mixin interface and acts as, possibly incomplete, mixin implementation.

@Retention(RetentionPolicy.RUNTIME)
@Target(TYPE)
public @interface Mixin {
  /** 
   * Class implementing mixin interface.
   */
  Class<?> impl();
}

The class which wants to extend mixin must be defined as abstract and must implement mixin interface. Class might extend more then one mixin.

The actual, non abstract implementation for mixin methods is build by helper class which here is called MixinBuilder.

Simple yet complete implementation of MixinBuilder using javassit library is presented below. It does not perform any kind of validation of the setup. Moreover it does not handle the case when more then one mixin defines and implement the same method or two mixins depend on each other. But all those limitations are quite easy extensions to presented code.

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;

public class MixinBuilder {
 private static Object invoke(Method method, Object target, 
    Object[] args) throws Exception {
  return target.getClass().getMethod(method.getName(),
    method.getParameterTypes()).invoke(target, args);
 }
 
 @SuppressWarnings("unchecked")
 private static <T> T newMixinInstance(final Object parent, 
    final Class<T> mixinImpl) {
  try {
   final ProxyFactory proxy = new ProxyFactory();
   proxy.setSuperclass(mixinImpl);
   return (T) proxy.create(null, null, new MethodHandler() {
    public Object invoke(Object target, Method method, 
      Method superMethod, Object[] args) 
      throws Throwable {
     // Delegate invocations of abstract methods 
     // to parent object.
     if (Modifier.isAbstract(method.getModifiers())) {
      return MixinBuilder.invoke(method, parent, args);
     }
     return superMethod.invoke(target, args);
    }
   });
  } catch (Exception e) {
   throw new IllegalArgumentException(e);
  }
 }
 
 @SuppressWarnings("unchecked")
 public static <T> T newInstance(final Class<T> mainClass) {
  try {
   final ProxyFactory proxy = new ProxyFactory();
   proxy.setSuperclass(mainClass);
   return (T) proxy.create(null, null, new MethodHandler() {
    private Map<Class<?>,Object> mixinMap = 
      new HashMap<Class<?>, Object>();
    
    public Object invoke(Object target, Method method, 
        Method superMethod, Object[] args) 
        throws Throwable {
     // Delegate invocations of abstract methods 
     // to mixin.
     if (Modifier.isAbstract(method.getModifiers())) {
      Class<?> mixinInterface = method.getDeclaringClass();
      if (!mixinMap.containsKey(mixinInterface)) {
       Mixin annotation = mixinInterface.getAnnotation(
          Mixin.class);
       final Class<?> mixinClass = annotation.impl();
       mixinMap.put(mixinInterface, 
          newMixinInstance(target, mixinClass));
      }
      Object mixin = mixinMap.get(mixinInterface);
      return MixinBuilder.invoke(method, mixin, args);
     }
     return superMethod.invoke(target, args);
    }
   });
  } catch (Exception e) {
   throw new IllegalArgumentException(e);
  }
 }

Sample usage of MixinBuilder might look like this:

@Mixin(impl = MixinAImpl.class)
 public interface MixinA {
  void a();
  void doA();
 }
 
 public abstract class MixinAImpl implements MixinA {
  public void a() {
   System.out.println("MixinAImpl.a()");
   doA();
  }
 }
 
 @Mixin(impl = MixinBImpl.class)
 public interface MixinB {
  void b();
  void doB();
 }
 
 public abstract class MixinBImpl implements MixinB {
  public void b() {
   System.out.println("MixinBImpl.b()");
   doB();
  }
 }
 
 public abstract class Test implements MixinA, MixinB {
  public void doA() {
   System.out.println("Test.doA()");
   b();
  }
  public void doB() {
   System.out.println("Test.doB()");
  }
  public void test() {
   System.out.println("Test.test()");
   a();
  }
 
  public static void main(String[] args) {
   MixinBuilder.newInstance(Test.class).test();
  }
 }

When executed it will display following output:

Test.test()
MixinAImpl.a()
Test.doA()
MixinBImpl.b()
Test.doB()

We can clearly see how execution of single method on Test class causes MixinAImpl execution which indirectly calls Test and MixinBImpl.

If you need more complete ready to use solution check out: Multiple Inheritance and Traits in Java

piątek, 25 lutego 2011

How to check if composite component's attribute is set?

Composite components are one of the nicest features of the facelets. They allow to easily bundle some parts of markup as reusable components.
One of the common problems with them is the inability to check if the actual attribute has been set on component usage. This has been partially solved in JSF 2.0 by allowing to set default value for an attribute but still it isn't perfect.
Here is my solution for this problem which is based on the observation how facelets pass values between different fragments of the markup.
Solution uses custom tag handler which will process its content only if the attribute with given name has been set for the composite component.

public class IfHasAttributeTagHandler extends TagHandler {
 private final TagAttribute name;

 public IfHasAttributeTagHandler(TagConfig config) {
  super(config);
  name = getRequiredAttribute("name");
 }

 public void apply(FaceletContext ctx, UIComponent parent)
  throws IOException, FacesException, ELException {
  if (ctx.getVariableMapper().resolveVariable(
   name.getValue(ctx)) != null) {
   nextHandler.apply(ctx, parent);
  }
 }
}

The sample usage of this component might look like this:

<c:set var="hasArg" value="false" />
<custom:ifHasAttribute name="arg">
  <c:set var="hasArg" value="true" />
</custom>

Of course in the similar way you can build component which will process its content only is the attribute hasn't been defined.

wtorek, 8 lutego 2011

HttpSession passivation and Spring Part 1

Many users of Spring framework forget about or are not aware of important requirement which states that all HttpSession attributes must be serializable if the session should be passivable.

Let's start with some simple web application which has two session beans: UserBean and EditOrderBean and two singletons: UserDAO and OrderDAO. Those beans might look like those:

public class OrderDAO { 
  // actual code is not important in this context
}

public class UserDAO { 
  // actual code is not important in this context
}

public class UserBean {
 private String login;
 // userDAO is managed by Spring
 private UserDAO userDAO;
 
 // constructor, getters and setters
}

public class EditOrderBean {
 private String item;
 private int quantity;
 // orderDAO is managed by Spring
 private OrderDAO orderDAO;
 // userBean is managed by Spring
 private UserBean userBean;
 
 // constructor, getters and setters
}

As simple as it seems it is not correct implementation and it will cause problems in distributed environment or on application server which has session passivation enabled. To fix this both UserBean and EditOrderBean bean classes must be serializable. To do so we should add Serializable interface to them and mark all non session bean references as transient.

public class UserBean implements Serializable {
 private String login;
 // userDAO is managed by Spring
 private transient UserDAO userDAO;
 
 // constructor, getters and setters
}

public class EditOrderBean implements Serializable {
 private String item;
 private int quantity;
 // orderDAO is managed by Spring
 private transient OrderDAO orderDAO;
 // userBean is managed by Spring
 private UserBean userBean;
 
 // constructor, getters and setters
}

After those changes session will passivate but unfortunately after activation both our beans will be missing references to the beans which has been marked as transient. To reset them we must use little known method from Spring's AutowireCapableBeanFactory interface called configureBean. It gets two arguments: existing bean instance and beans name and performs bean initialization.

Call to this method should be made just after session activation but before its usage. This can be achieved using HttpSessionActivationListener interface.

public class RestoreSpringSessionListener implements
  HttpSessionActivationListener {
 @Override
 public void sessionDidActivate(HttpSessionEvent sessionEvent) {
  HttpSession session = sessionEvent.getSession();
  ServletContext servletContext = session.getServletContext();
  WebApplicationContext webAppContext = WebApplicationContextUtils.
    getRequiredWebApplicationContext(servletContext);
  AutowireCapableBeanFactory autowireFactory = webAppContext.
    getAutowireCapableBeanFactory();

  // Iterate through all session attributes, check if they are 
  // Spring managed beans and if they are reconfigure them.
  Enumeration<String> names = session.getAttributeNames();
  while (names.hasMoreElements()) {
   String name = names.nextElement();

   // This checks only if the bean with given name is defined.
   // It does not check if it has session scope.
   if (webAppContext.containsBean(name)) {
    Object bean = session.getAttribute(name);

    // Reconfigure resored bean instance.
    bean = autowireFactory.configureBean(bean, name);
    session.setAttribute(name, bean);
   }
  }
 }

 @Override
 public void sessionWillPassivate(HttpSessionEvent sessionEvent) { 
 }
} 

Now you just need to register this listener in your web.xml:
<web-app ...>
  ...
  <listener>
    <listener-class>
      com.acme.RestoreSpringSessionListener
    </listener-class>
  </listener>
  ...
</web-app>

Please be aware that this solution works only with quite simple bean configurations. This means that it won't work for instance if you are using:
  • destroyable beans,
  • complex bean initialization,
  • proxies around beans,
  • aop-scoped proxies.

I will try to address at least some of those limitations in the third part of this article.

Another solution for given problem is a custom implementation of session scope. This will be presented in second part of this article.

środa, 29 grudnia 2010

Type safe Observer/Observable

Using generic design pattern in statically typed languages can lead to some problems related to type safety. For instance let's take a look at the implementation of Observer design pattern in Java which has been created in the pre generics era.
It consists of two classes namely Observer and Observable and in simplified form looks like this:

public interface Observer {
    void update(Observable observable);
}

public class Observable {
    public void addObserver(Observer observer) { }
    public void notifyObservers() { }
}

Let's assume that we want to have two distinct subclasses of Observer and Observable. ObserverA can observe instances of ObservableA only and ObserverB can observe instances of ObservableB only.


How should we define all those classes to enforce correct behaviour? As simple as this question seems to be the solution might not be as obvious for people who don't know generics too much.
The solution is to parametrize both Observer and Observable with two type parameters one for Observer subclass and the other one for Observable subclass.

public interface Observer<T extends Observer<T,O>, 
    O extends Observable<O,T>> {
    void update(O observable);
}

public class Observable<T extends Observable<T,O>, 
    O extends Observer<O,T>> {
    public void addObserver(O observer) { }
    public void notifyObservers() { }
}

public interface ObserverA extends 
    Observable<ObserverA, ObservableA> {
}

public class ObservableA extends 
    <ObservableA, ObserverA > {
}

Thanks to this ObserverA.update() will accept subclasses of ObservableA only and ObservableA.addObserver() will accept subclasses of ObserverA.
The same solution can be applied to any set of classes which depend on each other. In this context simply parametrize each of them with one type parameter for each of the classes.

wtorek, 28 września 2010

Lazy one-to-one inverse relationships in Hibernate

Many people are surprised when lazy loading of inverse (not owning) optional one-to-one relationships using Hibernate does not work for them out of the box.

Let's start with a short example:

@Entity
public class Person {
 private Animal animal;

 @OneToOne(optional = false)
 public Animal getAnimal() {
  return animal;
 }

 public void setAnimals(Animal animal) {
  this.animal = animal;
 }
}

@Entity
public class Animal {
 private Person owner;

 @OneToOne(fetch = FetchType.LAZY, optional = true, mappedBy = "animal")
 public Person getOwner() {
  return owner;
 }

 public void setOwner(Person owner) {
  this.owner = owner;
 }
}

Many developers expect that owner property of the Animal entity will not be loaded until it is accessed for the first time. This is true but only for relationships where the proxy object for the other end of the relationship can be used. In our example it won't work.

There are at least three well known solutions for this problem:
  1. The simplest one is to fake one-to-many relationship. This will work because lazy loading of collection is much easier then lazy loading of single nullable property but generally this solution is very inconvenient if you use complex JPQL/HQL queries.
  2. The other one is to use build time bytecode instrumentation. For more details please read Hibernate documentation: 19.1.7. Using lazy property fetching. Remember that in this case you have to add @LazyToOne(LazyToOneOption.NO_PROXY) annotation to one-to-one relationship to make it lazy. Setting fetch to LAZY is not enough.
  3. The last solution is to use runtime bytecode instrumentation but it will work only for those who use Hibernate as JPA provider in full-blown JEE environment (in such case setting "hibernate.ejb.use_class_enhancer" to true should do the trick: Entity Manager Configuration) or use Hibernate with Spring configured to do runtime weaving (this might be hard to achieve on some older application servers). In this case @LazyToOne(LazyToOneOption.NO_PROXY) annotation is also required.

But what if you don't want to modify the structure of your entities and don't want or cannot use bytecode instumentalization (there are some issues related to this).

There is one more undocumented solution. It requires some modifications in the entities code but thanks to this building and deployment process can remain untouched.

The idea is to fool Hibernate that the entity class which we want to use has been already instrumented. To do this your entity class has to implement FieldHandled or InterceptFieldEnabled interface.

@Entity
public class Animal implements FieldHandled {
 private Person owner;
 private FieldHandler fieldHandler;

 @OneToOne(fetch = FetchType.LAZY, optional = true, mappedBy = "animal")
 @LazyToOne(LazyToOneOption.NO_PROXY)
 public Person getOwner() {
  if (fieldHandler != null) {
   return (Person) fieldHandler.readObject(this, "owner", owner);
  }
  return owner;
 }

 public void setOwner(Person owner) {
  if (fieldHandler != null) {
   this.owner = fieldHandler.writeObject(this, "owner", this.owner, owner);
   return;
  }
  this.owner = owner;
 }

 public FieldHandler getFieldHandler() {
  return fieldHandler;
 }

 public void setFieldHandler(FieldHandler fieldHandler) {
  this.fieldHandler = fieldHandler;
 }
}

If you are using javassist as bytecode provider (default from Hibernate version 3.3.0.CR2) implement org.hibernate.bytecode.javassist.FieldHandled and if you are using CGLib implement net.sf.cglib.transform.impl.InterceptFieldEnabled.

Getters and setters for non-lazy properties requires no changes.

The last thing worth mentioning here is that Hibernate does not support one by one lazy properties loading. This means that if your entity class has more then one lazy properties all of them are going to be loaded during the first access to any of them (I know that this is stupid but this is how it is currently implemented).

czwartek, 16 września 2010

Mapping cyclic object references to XML using JAXB

With JAXB being de facto standard for XML to Java data binding it is hard not to use it in enterprise application. Because of this as a java developer sooner or later you will notice some serious limitations of it. One of the most painful is a lack of support for object cycles and repetitions.

Lets start with a simple java class which we want to serialize to XML using JAXB.

@XmlRootElement
public class Node {
 private List<Node> nodes;
 @XmlAttribute
 private String name;

 public Node() {
 }

 public Node(String name) {
  this.name = name;
 }

 @XmlElementRef 
 public List<Node> getNodes() {
  return nodes;
 }

 public void setNodes(List<Node> nodes) {
  this.nodes = nodes;
 }

 public void addNode(Node node) {
  if (nodes == null) {
   nodes = new ArrayList<Node>();
  }
  nodes.add(node);
 }
}

If we run following test code we will get self explanatory error.

public class Test {
 public static void main(String[] args) throws Exception {
  Node node1 = new Node("node1");
  Node node2 = new Node("node2");
  Node node3 = new Node("node3");
  node1.addNode(node2);
  node1.addNode(node3);
  node2.addNode(node1);
  node2.addNode(node3);
  node3.addNode(node1);
  node3.addNode(node2);
  
  JAXBContext context = JAXBContext.newInstance(Node.class);
  Marshaller marshaller = context.createMarshaller();
  marshaller.marshal(node1, System.out);
 }
}

Exception in thread "main" javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: 
A cycle is detected in the object graph.
This will cause infinitely deep XML: 
node.Node@1e9cb75 -> node.Node@c5c3ac -> node.Node@1e9cb75]

After spending a few hours on searching web for solution for this problem I haven't found any but I was able to came up with my own idea how to fix it.

First of all we need simple dummy XML adapter.

public class AnyTypeAdapter extends XmlAdapter<Object, Object> {
 public Object marshal(Object value) {
  return value;
 }

 public Object unmarshal(Object value) {
  return value;
 }
}

We need also to create wrapper class which will enable us to break cycles.

@XmlRootElement
public class ObjectWrapper {
 private static AtomicInteger nextId = new AtomicInteger(0);
 
 @XmlAttribute
 @XmlID
 private String id = String.valueOf(nextId.addAndGet(1));

 @XmlAttribute
 @XmlIDREF
 private ObjectWrapper ref;

 @XmlJavaTypeAdapter(AnyTypeAdapter.class)
 @XmlAnyElement(lax = true)
 private Object value;

 public ObjectWrapper() {
 }

 public ObjectWrapper(Object value) {
  this.value = value;
 }

 public Object getValue() {
  return value;
 }
 
 public void update(ObjectWrapper ref) {
  this.ref = ref;
  this.id = null;
  this.value = null;
 }

 public Object resolve() {
  return value == null ? 
    (ref == null ? null : ref.value) : 
    value;
 }
}

In order to make its usage easier we need to create another XML adapter.

public class ObjectWrapperAdapter extends 
  XmlAdapter<ObjectWrapper, Object> {
 public ObjectWrapper marshal(Object value) {
  return value == null ? 
    null : new ObjectWrapper(value);
 }

 public Object unmarshal(ObjectWrapper wrapper) {
  return wrapper == null ? 
    null : wrapper.resolve();
 }
}

Last part of the solution is a marshaller listener which will find repetitions in the object graph and transform them to XML id references (I'm using IdentityHashMap here but in some cases HashMap does make sense as well).

public class CycleListener extends Marshaller.Listener {
 private Map<Object, ObjectWrapper> objectMap = 
   new IdentityHashMap<Object, ObjectWrapper>();
 
 public void beforeMarshal(Object source) {
  if (source instanceof ObjectWrapper) {
   ObjectWrapper wrapper = (ObjectWrapper) source;
   if (objectMap.containsKey(wrapper.getValue())) {
    if (wrapper != objectMap.get(wrapper.getValue())) {
     wrapper.update(objectMap.get(wrapper.getValue()));
    }
   } else {
    objectMap.put(wrapper.getValue(), wrapper);
   }
  }
 }
}

With those four classes we need to change the Node class a little bit by applying ObjectWrapperAdapter to it. No other changes to the serialized class are needed.

@XmlJavaTypeAdapter(ObjectWrapperAdapter.class)
@XmlRootElement
public class Node {
 private List<Node> nodes;
 @XmlAttribute
 private String name;

 public Node() {
 }

 public Node(String name) {
  this.name = name;
 }

 @XmlElementRef 
 public List<Node> getNodes() {
  return nodes;
 }

 public void setNodes(List<Node> nodes) {
  this.nodes = nodes;
 }

 public void addNode(Node node) {
  if (nodes == null) {
   nodes = new ArrayList<Node>();
  }
  nodes.add(node);
 }
}

Finally we can rerun our test code. The only change we have to make is to register marshaller listener and wrap Node instance with ObjectWrapper (this is not needed if we know that the root object does not occur in any cycle).

public class Test {
 public static void main(String[] args) throws Exception {
  Node node1 = new Node("node1");
  Node node2 = new Node("node2");
  Node node3 = new Node("node3");
  node1.addNode(node2);
  node1.addNode(node3);
  node2.addNode(node1);
  node2.addNode(node3);
  node3.addNode(node1);
  node3.addNode(node2);

  JAXBContext context = JAXBContext.newInstance(
    Node.class, ObjectWrapper.class);
  Marshaller marshaller = context.createMarshaller();
  marshaller.setListener(new CycleListener());
  marshaller.marshal(new ObjectWrapper(node1), System.out);
 }
}

As a result we will get following XML.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<objectWrapper id="1">
 <node name="node1">
  <objectWrapper id="2">
   <node name="node2">
    <objectWrapper ref="1" />
    <objectWrapper id="4">
     <node name="node3">
      <objectWrapper ref="1" />
      <objectWrapper ref="2" />
     </node>
    </objectWrapper>
   </node>
  </objectWrapper>
  <objectWrapper ref="4" />
 </node>
</objectWrapper>

As we can see each node element is wrapped with objectWrapper element which has an id and a node or a reference to other objectWrapper's id.

This approach works also with more complex object structures. Simply add @XmlJavaTypeAdapter(ObjectWrapperAdapter.class) annotation to all classes which can cause cycles or you want to remain unique after deserialization.