Archive for the 'java' Category

Groovy vs. Google Collections: Round #2

Tuesday, April 8th, 2008

For Round #2 of our code challenge, Dan has responded to my initial provocation in spades with a efficient example of Google CollectionsMultiMap utilities. His model involves car makes and models, their associations, and the easiest way to travel between them. At the core of the problem is the fact that a make can have many models, and we want an easy collection that will have utilities to get the data from both ends. Touché, my good man, because groovy doesn’t have a utility that matches the MultiMap functionality.

In order to quickly emulate the same data structure, I was forced to push a bunch of single-element maps into a list! Yuck!

Setting up my collection
def cars = []
cars << ['Ford':'Taurus'] << ['Ford':'Focus'] << ['Ford':'Mustang']
cars << ['Chevrolet':'Malibu'] << ['Chevrolet':'Impala'] << ['Chevrolet':'Corvette']
cars << ['Dodge':'Charger'] << ['Dodge':'Avenger'] << ['Dodge':'Viper']

But at least I have something I can work with now, albeit not the optimal collection that MultiMap would have provided in this case.

The real logic
def printModels = { make, pair ->
    if (pair.any{it.key == make})
        println "$make makes ${(pair.values() as List)[0]}"
    make
}
def printMake = { model, pair ->
    if (pair.any{it.value == model})
        println "$model is made by ${(pair.keySet() as List)[0]}"
    model
}
cars.inject('Ford', printModels)
cars.inject('Chevrolet', printModels)
cars.inject('Dodge', printModels)
cars.inject('Impala', printMake)

All the work is done in the closures. If I had the MultiMap’s capabilities, I could have created a map that would store multiple values for each key (see Dan’s initial volley), and I could have just called get() to retrieve a set of those values. But my groovy closures are looking specifically for either the key or value in the list of single-element maps. The closures are meant to be used with the inject method of groovy collections. The first printModels closure expects the make to be injected into it, and then compares it to each map key to find whether the current pair should be printed out. The printMakes closure expects the model to be passed, comparing it to the pair values.

I was disappointed to find out that groovy’s map implementation had no inverse operation. In java, this is not possible, because a key can have only one value, and if you try to inverse, you might possibly have a key with many values, breaking java into tiny pieces. Because the MultiMap allows keys to have multiple values, there is no danger in inversing the positions of keys and values, which is very handy (again, see how Dan used it)

The calls to inject actually execute the closures that print out the strings. The first three print out the models for each make injected into the closure, and the last one injects a model and prints out its make.

So there are some pluses, some minuses to using groovy for this sort of problem. On one hand, my total lines of code are still under 20, which is less than Dan’s example. However, I’m using a Frankensteined collection (a list of single-element maps). Can we get the best of both worlds somehow?

You can add any java library to your groovy project, just like it was a java project.

So let’s add Google’s Collections package as see if we can use it with groovy to make our code nicer!

Groovy and Google’s collections hand-in-hand
import com.google.common.collect.*

def cars = Multimaps.newHashMultimap()
cars.put('Ford','Taurus')

Ok… let’s stop right there. The groovy programmer in me really wanted to add to the map using cars.’Ford’ = ‘Taurus’, but no dice. This isn’t a groovy map, it is a google map, so I’ve lost all my groovy functionality, which isn’t very groovy. And my script from this point on is going to look suspiciously like Dan’s java program. So what is the point of this experiment? Well, it lets me know that if I run into a situation where I’ll need the functionality of a MultiMap, I can easily import the google jar and whip out an inverse-able MultiMap collection. Only, I won’t be able to use all the sugary groovy syntax with it. It is still better to have the option.

In summary, I think the google java collections package is downright cool. Anything that makes programming simpler and easier is good for our business. Groovy is great, but if I were working in java today, I would love this package. Hell, I might even want to use it with groovy someday. Thanks to Dan Lewis for participating in my challenge and being a good sport.


Groovy vs. Google Collections: Round #1

Friday, April 4th, 2008

In my last post, Dan Lewis (my friend and former coworker) responded with some counter-code from Google’s collections package. Instead of attempting to snap back with some witty technical retort, I challenged Dan to a code-off. Groovy collections vs. Google collections (in Java). Here is round one, and I’m going first with an example of finding combinations of collections. Hopefully, you can soon find Dan’s response in Google collection code-style on his blog.

Create the lists
def boys = ['Paco', 'Sven', 'Roger', 'Emelio']
def girls = ['Julia', 'Prudence', 'Lucy']

Now we have two simple lists, one of boys and one of girls. So what if these are all dancers, and we’d like to know all the combinations of dancers there could be? With groovy, this is extremely easy.

Find the combinations of dancers
def combos = [boys, girls].combinations()

Could it be any easier? This creates a list of lists, each inner list containing a possible combination:

[[”Paco”, “Julia”], [”Sven”, “Julia”], [”Roger”, “Julia”], [”Emelio”, “Julia”], [”Paco”, “Prudence”], [”Sven”, “Prudence”], [”Roger”, “Prudence”], [”Emelio”, “Prudence”], [”Paco”, “Lucy”], [”Sven”, “Lucy”], [”Roger”, “Lucy”], [”Emelio”, “Lucy”]]

Now it would be nice if i could split the list up in some way, maybe keying by male or female. Groovy’s groupBy collection method is an easy way to do this. In the closure you provide, you simple return the key that you want to group the collection by, and it will return a map with that key pointing to a list of values. In the following example, because I know the first element of each combination is the boy and the second is the girl, I just specify a key by element position.

Grouping the combinations
def groupedByBoys = combos.groupBy { it[0] }
def groupedByGirls = combos.groupBy { it[1] }

Which returns these two groupings:

Grouped by boys
[”Emelio”:[[”Emelio”, “Julia”], [”Emelio”, “Prudence”], [”Emelio”, “Lucy”]], “Roger”:[[”Roger”, “Julia”], [”Roger”, “Prudence”], [”Roger”, “Lucy”]], “Sven”:[[”Sven”, “Julia”], [”Sven”, “Prudence”], [”Sven”, “Lucy”]], “Paco”:[[”Paco”, “Julia”], [”Paco”, “Prudence”], [”Paco”, “Lucy”]]]
Grouped by girls
[”Lucy”:[[”Paco”, “Lucy”], [”Sven”, “Lucy”], [”Roger”, “Lucy”], [”Emelio”, “Lucy”]], “Prudence”:[[”Paco”, “Prudence”], [”Sven”, “Prudence”], [”Roger”, “Prudence”], [”Emelio”, “Prudence”]], “Julia”:[[”Paco”, “Julia”], [”Sven”, “Julia”], [”Roger”, “Julia”], [”Emelio”, “Julia”]]]

Beat that, Google Collections!


Mapping Java 5 enums with Hibernate

Sunday, September 23rd, 2007

Hibernate is used to map java objects to a relational database. Ideally, you would like your java object model to be as object-oriented as possible. It is also nice to be able to use features like java 5 enums while coding the object model. In this tutorial, I’ll share with you how I ended up mapping a simple object model using java 5 enums into Hibernate.

I’ve found the best way to jumpstart yourself into using Hibernate is to go through the official tutorial on the Hibernate site.

A Simple Example

I have a Beer object that corresponds directly to a BEER table in a database. The Beer object can wither be an “Ale” or a “Lager”, and there may be more types in the future. So the database schema looks like this:

Simple Beer schema
+--------------------+
| BEER               |
+--------------------+           +----------------+
| NUMBER  | ID       |           | BEER_TYPE      |
| VARCHAR | BRAND    |           +----------------+
| NUMBER  | TYPE     | FK------- | NUMBER  | ID   |
| NUMBER  | VOLUME   |           | VARCHAR | NAME |
+--------------------+           +----------------+

It is pretty straightforward how to create a java class to represent this data. Ideally, I would like to use a java 5 enum object to keep track of the beer type, so I use it within my data object to specify type:

Beer Data Object
public class Beer {
    private BeerType type;
    private String brand;
    private double volume;

    public BeerType getType() {
        return type;
    }

    public void setType(BeerType type) {
        this.type = type;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getVolume() {
        return volume;
    }

    public void setVolume(double volume) {
        this.volume = volume;
    }
}

The BeerType enum will simply specify the type of beer for each Beer object. This enum is going to map directly to the BEER_TYPE table. So I’ve given each beer type its own id through the private internal enum constructor. There is an accessor method for hibernate to retrieve the id when it needs to do the mapping.

BeerType enum
public enum BeerType {
    UNKNOWN(0), ALE(1), LAGER(2);

    private int id;

    private BeerType(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

}

One of the first things I found when I started searching the internet for ways to map Java 5 enums to a database using Hibernate was this article on the Hibernate page. It shows an implementation of the Hibernate UserType in a way that will allow an enum to be used within a hibernate key mapping. So if I create a custom type definition in the key-mapping that uses the GenericEnumUserType class as the class, and passes in the actual BeerType enum classpath as a parameter, I can do the work to break out the enum details in the GenericEnumUserType implementation.

Hibernate key-mapping for Beer
<hibernate-mapping>
    <typedef class="net.dangertree.GenericEnumUserType" name="beerType">
        <param name="enumClassName">net.dangertree.BeerType</param>
        <param name="identifierMethod">getId</param>
    </typedef>

    <class name="net.dangertree.Beer" table="BEER">
        <id name="id" type="int" column="ID">
            <generator class="native"/>
        </id>
        <property name="type" type="beerType" column="TYPE"/>
        <property name="brand" type="string" column="BRAND"/>
        <property name="volumn" type="double" column="VOLUME"/>
    </class>
</hibernate-mapping>

Here is the full code for the GenericEnumUserType class that I used to help map my enums into Hibernate. Reflection is used to find an “identifier” method in the enum that will get the id for each value. I have specified in the type-def in my key mapping that I’m going to use the getId() method of my enum to get an identifying attribute. By default, the class will look for the inherent name method of enum, but I’m using ids as my identifier.

The two method objects are grabbed and saved, then called in the null-safe setter and getter deeper within the Hibernate workings.

This class implementation of UserType is not exactly the same as any of those listings on the hibernate article I mentioned earlier. I had to make several minor changes to get it working with this code.
Generic Enum UserType implementation
import org.hibernate.HibernateException;
import org.hibernate.type.NullableType;
import org.hibernate.type.TypeFactory;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class GenericEnumUserType implements UserType, ParameterizedType {
    private static final String DEFAULT_IDENTIFIER_METHOD_NAME = “name”;
    private static final String DEFAULT_VALUE_OF_METHOD_NAME = “valueOf”;

    private Class enumClass;
    private Class identifierType;
    private Method identifierMethod;
    private Method valueOfMethod;
    private NullableType type;
    private int[] sqlTypes;

    public void setParameterValues(Properties parameters) {
        String enumClassName = parameters.getProperty(”enumClassName”);
        try {
            enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
        } catch (ClassNotFoundException cfne) {
            throw new HibernateException(”Enum class not found”, cfne);
        }

        String identifierMethodName = parameters.getProperty(”identifierMethod”,
            DEFAULT_IDENTIFIER_METHOD_NAME);

        try {
            identifierMethod = enumClass.getMethod(identifierMethodName,
                new Class[0]);
            identifierType = identifierMethod.getReturnType();
        } catch (Exception e) {
            throw new HibernateException(”Failed to obtain identifier method”,
                e);
        }

        type = (NullableType) TypeFactory.basic(identifierType.getName());

        if (type == null)
            throw new HibernateException(”Unsupported identifier type ”
                + identifierType.getName());

        sqlTypes = new int[] { type.sqlType() };

        String valueOfMethodName = parameters.getProperty(”valueOfMethod”,
            DEFAULT_VALUE_OF_METHOD_NAME);

        try {
            valueOfMethod = enumClass.getMethod(valueOfMethodName,
                new Class[] { identifierType });
        } catch (Exception e) {
            throw new HibernateException(”Failed to obtain valueOf method”, e);
        }
    }

    public Class returnedClass() {
        return enumClass;
    }

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
            throws HibernateException, SQLException {
        Object identifier = type.get(rs, names[0]);
        if (rs.wasNull()) {
            return null;
        }

        try {
            return valueOfMethod.invoke(enumClass, new Object[] { identifier });
        } catch (Exception e) {
            throw new HibernateException(”Exception while invoking ”
                + “valueOf method ‘” + valueOfMethod.getName() + “‘ of ”
                + ”enumeration class ‘” + enumClass + “‘”, e);
        }
    }

    public void nullSafeSet(PreparedStatement st, Object value, int index)
            throws HibernateException, SQLException {
        try {
            if (value == null) {
                st.setNull(index, type.sqlType());
            } else {
                Object identifier = identifierMethod.invoke(value,
                    new Object[0]);
                type.set(st, identifier, index);
            }
        } catch (Exception e) {
            throw new HibernateException(”Exception while invoking ”
            + “identifierMethod ‘” + identifierMethod.getName() + “‘ of ”
            + ”enumeration class ‘” + enumClass + “‘”, e);
        }
    }

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

    public Object assemble(Serializable cached, Object owner)
            throws HibernateException {
        return cached;
    }

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

    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    public boolean equals(Object x, Object y) throws HibernateException {
        return x == y;
    }

    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    public boolean isMutable() {
        return false;
    }

    public Object replace(Object original, Object target, Object owner)
            throws HibernateException {
        return original;
    }
}

Ok, there is only one problem now. The DEFAULT_VALUE_OF_METHOD_NAME method is specified by default to be valueOf, and I have not provided a parameter to override that in the type-def. So in order for my enum to match this, I need to add a valueOf method to my enum. And when the nullSafeGet method calls the “valueOfMethod“, it sends it an identifier as a parameter, so our valueOf method needs to take an int id as a parameter.

Modified BeerType enum
public enum BeerType {
    UNKNOWN(0), ALE(1), LAGER(2);

    private int id;

    private BeerType(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public static BeerType valueOf(int id) {
        switch (id) {
            case 1: return ALE;
            case 2: return LAGER;
            default: return UNKNOWN;
        }
    }
    
}

Now I have my data object, the enum it is using, my key-mapping, and an implementation of UserType that provides a way to access the enum through a type-def element in the key-mapping.

It’s all working for me now! Does anyone have any questions or comments? This is the very first time that I have interacted with hibernate, so I’m a little bit shaky with the details (especially the UserType implementation).

Edit: correction of mapping file pointed out by commenters.


I *heart* winning “I *heart* POJOs” stickers

Sunday, July 29th, 2007
my bumper sticker

Now everyone will know!

I won a bumper sticker!


Implementing a deep clone using private copy constructors in Java

Thursday, July 5th, 2007

One of the drawbacks of Java is that there is no quick-and-easy way to copy an object into a new memory location. The Object class has a clone() method, but this method will not perform a complete memory location copy of that object. If the object being cloned has any references to other objects within it, those references will be carried over to the clone. That means that changes to the clone will result in changes to the original object, and this is not usually what is wanted with an object is cloned.

One method of creating a “deep clone” of a Java Object is to serialize it to XML, then read it back into the program from the XML stream into a new object (serializing to disk also works fine, but takes longer). I may go into detail about this method in a future post. This is usually resorted to when the object structure that needs a deep copy is legacy in nature, and there were no conveniences for copying included in the design.

The method that I’m going to detail in this post will add copy constructors to each object that will need to be cloned within the object model.

For this example, let’s say I have a Data object that contains:

  • one Double (the double wrapper class)
  • one Integer (the int wrapper class)
  • one String (duh)
  • one Person (a custom data class)

Here is the class, with all its mutator methods. Note the private constructor and the getCopy() method that uses it.

Data.java

package net.dangertree.copyconstructors;

public class Data {
	private Double doubleValue;
	private Integer integerValue;
	private String stringValue;
	private Person person;

	public Data(Double d, Integer i, String s, Person person) {
		super();
		this.doubleValue = d;
		this.integerValue = i;
		this.stringValue = s;
		this.person = person;
	}

	/*
	 * This method must ensure that all inner data elements
	 * are created into new object references.
	 */

	private Data(Data toCopy) {
		this.doubleValue = new Double(toCopy.getDoubleValue());
		this.integerValue = new Integer(toCopy.getIntegerValue());
		this.stringValue = new String(toCopy.getStringValue());
		// we rely on 'Person' to create its own copy
		this.person = toCopy.getPerson().getCopy();
	}


	public Data getCopy() {

		return new Data(this);

	}

	public Double getDoubleValue() {
		return doubleValue;
	}

	public void setDoubleValue(Double d) {
		this.doubleValue = d;
	}

	public Integer getIntegerValue() {
		return integerValue;
	}

	public void setIntegerValue(Integer i) {
		this.integerValue = i;
	}

	public String getStringValue() {
		return stringValue;
	}

	public void setStringValue(String s) {
		this.stringValue = s;
	}

	public Person getPerson() {
		return person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}

	@Override
	public String toString() {
		return "Double valuet" + doubleValue + "nInteger valuet"
				+ integerValue + "nString valuet" + stringValue
				+ "nPersont" + person.toString() + "n";
	}
}

There is a private constructor that actually creates a copy, while the getCopy() method is able to call the private constructor, passing in the this keyword, meaning to make a copy of the object that getCopy() is being called on. The job of the private constructor is to guarantee that each element that needs to be created for the copy is pointing to a new object in memory, but has the same values as the parameter Data being passed in. Double, Integer, and String all provide public constructors, making it easy for us to create new objects with new memory locations. But for a custom data class like Person, we need to ensure that it is copyable as well.

It would be logical to create an Copyable interface that provides a getCopy() method within its contract. Then both the Data and Person could implement it.

The Person class must also be able to provide a copy of itself, and it can use the same method as Data.

Person.java

package net.dangertree.copyconstructors;

public class Person {
	private String name;
	private int age;

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	private Person(Person toCopy) {
		this.name = new String(toCopy.getName());
		this.age = toCopy.getAge();
	}


	public Person getCopy() {

		return new Person(this);

	}

	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return name + ", " + age;
	}

	@Override
	public boolean equals(Object obj) {
		if(this == obj)
			return true;
		if((obj == null) || (obj.getClass() != this.getClass()))
			return false;
		Person compareTo = (Person)obj;
		if (compareTo.getAge() == age
				&& compareTo.getName().equals(name)) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		int hash = 1;
	    hash = hash * 31 + age;
	    hash = hash * 31
	                + (name == null ? 0 : name.hashCode());
	    return hash;
	}
}
If you override the equals() method, always override the hashCode() method as well!

Now if we provide a class to put some collections together and show how the deep copying works…

DataCopier.java

package net.dangertree.copyconstructors;

public class DataCopier {

	public static void main(String[] args) {
		// create data from scratch
		Data d1 = new Data(1.1, 2, "three", new Person("Matt Taylor", 28));

		System.out.println("Data 1: ");
		System.out.println(d1);

		// make a copy of the data to toy with
		Data d2 = d1.getCopy();
		System.out.println("Deep copy of Data 1 before changes:");
		System.out.println(d2);

		// now change the copy a little
		d2.setDoubleValue(3.14);
		d2.setIntegerValue(500);
		d2.setStringValue("changed copy");
		d2.getPerson().setAge(29);

		System.out.println("Deep copy of Data 1 after changes:");
		System.out.println(d2);

		System.out.println("The original, unchanged Data 1:");
		System.out.println(d1);
	}
}

If you run this, it produces the following output:

Data 1:
Double value 1.1
Integer value 2
String value three
Person Matt Taylor, 28

Deep copy of Data 1 before changes:
Double value 1.1
Integer value 2
String value three
Person Matt Taylor, 28

Deep copy of Data 1 after changes:
Double value 3.14
Integer value 500
String value changed copy
Person Matt Taylor, 29

The original, unchanged Data 1:
Double value 1.1
Integer value 2
String value three
Person Matt Taylor, 28

As you can see, the original copy is unchanged, even after its copy is altered. That is because all its references are pointing to different memory locations in the heap. This is what we want to happen with a deep copy.

Here is also a unit test that proves this:

CopyTest.java

package test.net.dangertree.copyconstructors;

import junit.framework.TestCase;
import net.dangertree.copyconstructors.Data;
import net.dangertree.copyconstructors.Person;

public class CopyTest extends TestCase {

	public void test_data_is_deep_copied() throws Exception {
		Data d1 = new Data(1.1, 2, "three", new Person("Matt Taylor", 28));
		Data d2 = d1.getCopy();

		// checks that the variables do not reference the same object
		assertNotSame(d1, d2);

		// checks that the objects contain the same data values
		assertEquals(d1.getDoubleValue(), d2.getDoubleValue());
		assertEquals(d1.getIntegerValue(), d2.getIntegerValue());
		assertEquals(d1.getStringValue(), d2.getStringValue());
		assertEquals(d1.getPerson(), d2.getPerson());

		// checks that the variables within the data do not reference
		// the same objects
		assertNotSame(d1.getDoubleValue(), d2.getDoubleValue());
		assertNotSame(d1.getIntegerValue(), d2.getIntegerValue());
		assertNotSame(d1.getStringValue(), d2.getStringValue());
		assertNotSame(d1.getPerson(), d2.getPerson());

	}

}

Finally, some things to remember:

  • Do not provide a public copy constructor. For more information on why, here is a good article.
  • The private constructor must ensure that all attributes are recreated from the incoming parameter to copy with a reference to a different memory location. For primitives, this happens automatically, but for objects you have to make sure.
  • All attribute objects must be easily copied if you want to make an object copyable. For this example, the primitive wrapper classes (Double and Integer) and String make it easy for you to create a copy with a public constructor that takes primitives or a immutable string. For your custom classes, you can provide a getCopy() and a matching private copy constructor to do the same job.
  • The Object.clone() method does not provide a deep copy. It will create a new object in memory, but all its attributes will point to the cloned object’s memory locations. So altering the attributes of the clone can potentially change the original.

Update: Eric Burke has helpfully provided a tip here. To paraphrase, there is no need to clone immutable fields like Double, Integer, and String

After copying an object in the way I suggest, both share references to the same underlying immutable fields. If you change one of these references in the original (or copied) object, the two objects no longer share references. Since the values are immutable, you can only “change” the value by pointing to entirely new references.

Get his improved code update here.