The Gerry Power technique on a base class
This technique was documented in a
hibernate forum by Gerry Power. Its on page 8 of a 9 page discussion on
the issue of equals and hashcode.
To me this technique is going to be just about as good as it gets for Developers who do not want to
use UUID and I have taken the liberty of reproducing the code Gerry posted verbatem.
public class BaseModel implements Serializable {
private volatile Object object;
private Long id;
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public boolean equals(Object obj) {
final boolean returner;
if (obj instanceof BaseModel) {
return getObject().equals(((BaseModel)obj).getObject());
} else {
returner = false;
}
return returner;
}
public int hashCode() {
return getObject().hashCode();
}
private Object getObject() {
if (object != null || object == null && id == null) {
if (object == null) { //Avoid the performance impact of synchronized if we can
synchronized(this) {
if (object == null)
object = new Object();
}
}
return object;
}
return id;
}
}
The downside I see for this technique is that perhaps not all your Ids will be of the same
type (Long in the code above) and for some they may not like specifying a base class for
their Entity Beans for whatever reason.
Gerry Power technique by byte code generation
For me this technique was pretty darn good and I felt that some people may want
Ebean to automatically implement this technique on Entity Beans via code generation.
The upside is that without doing any work you can use equals() to compare
Reference/Proxy objects with Entity Beans that are fetched back from queries.
The downside is that you can not use the byte code generated form to compare a
'Vanilla' entity bean with a 'byte code generated' entity bean. That is, Ebean can
implement override the generated code but of course your vanilla beans are always
left as is.
Topic topicRef = (Topic)Ebean.getReference(Topic.class, 21);
Topic topic0 = (Topic)Ebean.find(Topic.class, 21);
Topic topic1 = (Topic)Ebean.find(Topic.class, 21);
// these are all true
topicRef.equals(topic0);
topicRef.equals(topic1);
topic0.equals(topic1);
Topic vanillaTopic = new Topic();
vanillaTopic.setId(21);
// this is a vanilla bean - no byte code generation
// and this will be false (which may confuse people?)
vanillaTopic.equals(topic0);
In Ebean the property ebean.equalsmode controls whether the equals and hashcode
methods are generated. The valid values are "always","never","ifabsent" and the default is
"always".
Additionally there is the EqualsMode Annotation that can be used to control the behaviour
for a specific bean if required.
|