Announcing Pojomatic 1.0
Version 1.0 of Pojomatic has
been released. Pojomatic provides an easy way to implement
the equals(Object)
, hashCode()
and toString()
methods inherited
from java.lang.Object
. The typical work needed
for most classes is:
import org.pojomatic.Pojomatic;
import org.pojomatic.annotations.AutoProperty;
@AutoProperty // tells Pojomatic to use all non-static fields.
public class Pojo {
// Fields, getters and setters...
@Override public boolean equals(Object o) { return Pojomatic.equals(this, o); }
@Override public int hashCode() { return Pojomatic.hashCode(this); }
@Override public String toString() { return Pojomatic.toString(this); }
}
While this is adequate more most cases, there are numerous ways to
customize how Pojomatic will build up the implementations of
the equals
, toString
and hashCode
methods. The
@AutoProperty
annotation can instruct Pojomatic to use fields or getters to accesses
properties. Alternatively, one can annotate individual fields and/or
accessor methods with the
@Property
annotation to include them explicitely, or to exclude certain
properties if @AutoProperty
is being used. For any
property, a
@PojomaticPolicy
can be set to indicate which methods the property should be included
in. By default, a property is used
for each of the equals
, hashCode
and toString
methods, but any combination is possible,
subject to the restriction that if a property is used
for hashCode
, then it must be used
for equals
as well.
Proper implementation of equals for class hierarchies
As discussed in
How to
Write an Equality Method in Java, challenges arise in
satisfying the contract for equals
when class hierarchies
come into play. The solution suggested in that article is to
introduce an additional method, canEqual
, which the
implementation of equals
will use to ensure that
instances of a parent class do not accidentally declare themselves to
be equal to an instance of a subclass which has
redefined equals
. If all the classes in a hierarchy use
Pojomatic, this step is not necessary; Pojomatic keeps track of
whether instances of two related classes can be equal to each other or
not via the
areCompatibleForEquals
method. Two classes are compatible for
equality if they each have the same set of properties designated for
use with the equals
method. If a subclass has a need to
implement the equals
method without using Pojomatic, it
can be annotated with
@OverridesEquals
to indicate that it is not compatible for equality with it's parent class.
Comparing two Pojomated instances
A common use of the equals
method is to facilitate the use
of the assertEquals
methods of JUnit or TestNG.
When assertEquals
fails, the exception method includes
the toString
representation of each instance. One pain point which no
doubt will be familiar to many is that of trying to determine why two
instances are not equal when they have a large number of properties.
Often, the only option is to copy the failure message into an editor
which allows comparing the toString
representations to look for
differences. Pojomatic helps address this by adding
method, Pojomatic.diff
which can reveal the differences between two instances of a Pojomated
class.
The PojomaticTestUtils
library leverages this capability to provide
an assertEqualsWithDiff
method which will call out the
differences between two instances in the failure messaged in the event
that they are not equal.
Getting Pojomatic
Pojomatic is available on the central maven repository; if you use
maven, it is just a dependency away:
<dependency>
<groupId>org.pojomatic</groupId>
<artifactId>pojomatic</artifactId>
<version>1.0</version>
</dependency>
Others can download Pojomatic from
the
Sourceforge project page