Showing posts with label Dozer. Show all posts
Showing posts with label Dozer. Show all posts

Wednesday, November 10, 2010

Is Open Session in View an AntiPattern?

A friend of mine pointed me to a willingly provocative article that describes Open Session in View as an AntiPattern. After sharing some thoughts with him, I've decided to post them here.

I agree on the N +1 queries problem, but unless (and until) you have devastating impacts on performances I would not worry about it, applying a YAGNI approach. On the other hand, if a view requires a lot of fetches maybe DTOs come in useful (and I would suggest Dozer). This also semplifies the objects exposed, thus hiding from the "high" layers of the application all the complexities that exist within the domain.

Personally, one of the reasons for which I found Struts 1 frustrating - yet much better than the proprietary framework we were using at the time - was the need for form beans, which lead to tons of duplications (no Dozer yet, a long time ago in a galaxy far far away we only had some Commons Beanutils) which is normally bad. OK, forget the "normally" part.

As a general rule I think that exposing domain objects can be accepted if and only if they are true domain objects, not beans with a bunch of setters and getters and transaction scripts in disguise, otherwise you could bypass many of the application logics and end up with an unmanageable mess.

And, talking about layers leaking, I would also like to quote a couple of sentences from the Domain-Driven Design Using Naked Objects book which I suggest as a very interesting and useful reading:

It takes real skill to ensure the correct separation of concerns between these layers, if indeed you can get an agreement to what these concerns really are. Even with the best intentions, it's all too easy for custom-written layers to blur the boundaries and put (for example) validation in the user interface layer when it should belong to the domain layer. At the other extreme, it's quite possible for custom layers to distort or completely subvert the underlying domain model.


The leaking of the persistence layer is not good per se, but if it does not become a problem you can live with it. As always, it depends on circumstances: why should a spend an incredible amount of resources (which means time and money) to obtain perfect isolation if I don't need it?

In general I think Open Session in View to be a good solution to manage database connections, but it would be even better leverage this strategy with join fetch queries for the most important relations. After all, when writing a service or a facade we know what objects will be needed: this does not mean that the domain or the controller should depend on the presentation layer (they must not!), but pretend that we don't know anything about it is just a waste of time. So, for example, if our facade has a result factory this could be a nice place to eagerly load all objects we know the presentation layer will need; if the view still needs more objects the open session can provide them on the fly: in this way we can optimize the most important parts and live with the rest.

Wednesday, November 3, 2010

Dozer and enums

While trying to map a persistent heavyweight class to a cleaner (and much smaller) POJO I also wanted to substitute some String parameters of the persistent class to Enums. The tool of choice is Dozer, of which I already wrote.

As I had the possibility to create the POJO from scratch I choose only the properties I needed and used the same names of the persistent class, thus having no need to write a custom mapping at all.

To check that everything was working fine I wrote a unit test - what else would you expect? :-) - as simple as that:
@Test
public void testPojoToPersistenceEntity() {
System.out.println("testPojoToPersistenceEntity");
MyPojo pojo = new MyPojo(
propOne,
propTwo,
propThree,
propFour);
MyPersistentClass persistent = mapper.map(pojo, MyPersistentClass.class);
assertNotNull(persistent);
assertEquals(propOne, persistent.getPropOne());
assertEquals(propTwoTxt, persistent.getPropTwo());
assertEquals(propThreeTxt, persistent.getPropThree());
assertEquals(propFour, persistent.getPropFour());
}
I run the test and got a green bar for free. You may notice that in the comparison there are a couple of different variables: these are the names of the Enums, and I was quite pleased with the fact that Dozer had silently mapped them just as I expected.

Happy as a clam I wrote another test for the other way round:
@Test
public void testPersistenceEntityToExistingPojo() {
System.out.println("testPersistenceEntityToExistingPojo");
MyPersistentClass persistent = new MyPersistentClass(
propOne,
propTwoTxt,
propThreeTxt,
propFour);
persistent.setPropFive(propFive);
persistent.setPropSix(propSix);
MyPojo pojo = new MyPojo(
propOne,
propTwo,
propThree,
propFour);
assertEquals(0d, pojo.getPropFive(), 0.01d);
assertEquals(0d, pojo.getPropSix(), 0.01d);
mapper.map(persistent, pojo);
assertEquals(propFive, pojo.getPropFive(), 0.01d);
assertEquals(propSix, pojo.getPropSix(), 0.01d);
}
Still smiling I hit the CTRL+F6 combination and... WTF? red bar?
org.dozer.MappingException: Illegal object type for the method 'setPropTwo'.
Expected types:
my.package.MyEnum
Actual types:
java.lang.String
Hmmm... weird... but not too much after all, I had been too optimistic.

After a little investigation, and taken for granted that I didn't want to write a custom mapper for each and every enumeration I could need, given the current conditions of use of the POJO I tried to map a one-way relationship. The problem is that when you mark a field as one-way Dozer only maps from <class-a> to <class-b>, while I needed exactly the opposite behaviour. Changing the order of the classes was not an option as we use the convention of mapping all the domain classes as <class-a> so I had to revert to the <field-exclude> syntax:
<mapping>
<class-a>my.model.package.MyPersistentClass</class-a>
<class-b>my.package.MyPojo</class-b>
<field-exclude type="one-way">
<a>propTwo</a>
<b>propTwo</b>
</field-exclude>
<field-exclude type="one-way">
<a>propThree</a>
<b>propThree</b>
</field-exclude>
</mapping>
Not exactly what I had in mind, because it doesn't let me create a new instance of a POJO, but for now it will suffice.

Any hints?

Friday, October 15, 2010

Meet Dozer

Integration between systems is one of the most typical reasons of failure in complex projects. Yet, we find ourselves doing it day after day, so after some strategic mapping you have to get your hands dirty and map your wonderful objects to that incredible garbage other vendors still insist to call code. Or was it the other way round?

Let's assume a simple interaction via web services exposed on, say, an i-Series platform. I don't know whether all RPGLE programmers work in the same way, but almost all services of that kind I've seen so far have a single port with a thousand parameters for a hundred of different purposes and it is up to you to try and understand which of them must be used in which occasion. If that was not enough (and for me it is) it seems there is a contest for the use of the most cryptic parameter names, for which vowels seem to be banished and six characters is considered more than ehough (when not a waste of space).

One of the many things you learn with DDD is that code should be as close as possibile to your mental representation of the domain: well, LDLSDC does not make me think of a list of documents, but maybe it's my fault.

That said, before I use those objects in my code I'll have to convert them. The typical mapper has a signature similar to the following one:
public MyObject convert(YourObject yours, MyObject mine)
or
public MyObject convert(YourObject yours, MyObject.class)
The implementation is normally something like this:
myObject.setPropertyOne(yourObject.getPropertyOne);
myObject.setPropertyTwo(yourObject.getPropertyTwoButHasDifferentName)
(repeat ad lib for each property to be mapped)

This is very frustrating and most of all error prone. This is where several libraries step forward, most of them based on reflection, each of them having pluses and minuses. So far, the most interesting one I've found is Dozer, a bean to bean mapper that recursively copies data from one object to another (of a different type, of course! where would the fun be otherwise?). By the way, integrating different systems is just one of many reasons you have for mapping between different objects.

Using Dozer is just as easy as downloading the jar file, adding it to the classpath (don't forget the dependencies!) and coding right away:
Mapper mapper = new DozerBeanMapper();
Destination destination = mapper.map(source, Destination.class);
(almost utterly copied from the official tutorial). That's it. All fields with the same name are automagically mapped, with Dozer taking care of the necessary conversions (at least the more common ones). Should you need to customize mappings you may add some xml files that define how Dozer should behave:
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">

<configuration>
<stop-on-errors>true</stop-on-errors>
<date-format>MM/dd/yyyy HH:mm</date-format>
<wildcard>true</wildcard>
</configuration>

<mapping>
<class-a>yourpackage.yourSourceClassName</class-a>
<class-b>yourpackage.yourDestinationClassName</class-b>
<field>
<A>yourSourceFieldName</A>
<B>yourDestinationFieldName</B>
</field>
</mapping>

other custom class mappings would go here.......

</mappings>
And this is copied from the official manual.

You can also introduce a custom converter that you can reuse through your application:
<converter type="org.dozer.converters.TestCustomConverter" >
<class-a>org.dozer.vo.CustomDoubleObject</class-a>
<class-b>java.lang.Double</class-b>
</converter>
and its corresponding class:
public class TestCustomConverter implements CustomConverter {

public Object convert(Object destination, Object source, Class destClass, Class sourceClass) {
if (source == null) {
return null;
}
CustomDoubleObject dest = null;
if (source instanceof Double) {
// check to see if the object already exists
if (destination == null) {
dest = new CustomDoubleObject();
} else {
dest = (CustomDoubleObject) destination;
}
dest.setTheDouble(((Double) source).doubleValue());
return dest;
} else if (source instanceof CustomDoubleObject) {
double sourceObj = ((CustomDoubleObject) source).getTheDouble();
return new Double(sourceObj);
} else {
throw new MappingException("Converter TestCustomConverter used incorrectly. Arguments passed in were:" + destination + " and " + source);
}
}
}
And now a personal reminder: if you have to map an array of objects, but you know the types that you will find in specified positions AND want to avoid class cast exceptions (and I guess you do), you can use this syntax:
<field>
<a>myObjects[0]</a>
<b>other.propOne</b>
<a-hint>java.lang.Long</a-hint>
</field>
<field>
<a>myObjects[1]</a>
<b>other.propTwo</b>
<a-hint>java.lang.Short</a-hint>
</field>
Next thing I'm gonna try is the mapping for POJOs and JAXB objects...