Some approach for writing equials() and hashCode()

The problem described in details in http://www.hibernate.org/109.html The problem is that if we implement equals()/hashCode() as comparison and hashCode() of entity’s ids (see http://djeang.blogspot.com/2005/08/override-equals-and-hashcode-methods.html) then the hashCode() (and, possibly, equals()) will change after saving entities if ids are generated by DB. To solve this issue I can suggest to use inner classes with equals()/hashCode(). It will not affect Hibernate’s internal collections taskflow, but will allow you to use ids in equals()/hashCode() after entities are persisted. On other hand hashCode() and equals() will not change in your persistent objects after you have saved it.

 public class Test3 { static class SomeEntity { private Integer id; private String data; public SomeEntity() { super(); } public SomeEntity(Integer id, String data) { super(); this.id = id; this.data = data; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getData() { return data; } public void setData(String data) { this.data = data; } public class SomeEntityId { private SomeEntity link = null; public SomeEntityId(SomeEntity link) { super(); this.link = link; } @Override public boolean equals(Object obj) { if (this == obj) return true; if ((obj == null) || (obj.getClass() != this.getClass())) return false; if (this.link.getClass() != ((SomeEntityId) obj).getLink().getClass()) return false; Integer thisId = link.getId(); Integer otherId = ((SomeEntityId) obj).getLink().getId(); if ((thisId == null) || (otherId == null)) throw new RuntimeException("Id not defined!"); return thisId.equals(otherId); } @Override public int hashCode() { Integer thisId = link.getId(); if (thisId == null) throw new RuntimeException("Id not defined!"); return thisId.hashCode(); } public SomeEntity getLink() { return link; } }; public SomeEntityId getDTO() { return new SomeEntityId(this); } } public static void main(String[] args) { SomeEntity e0   = new SomeEntity(null, "no id"); SomeEntity e1 = new SomeEntity(1, "e1"); SomeEntity e2 = new SomeEntity(2, "e2"); SomeEntity e3 = new SomeEntity(3, "e3"); SomeEntity e33 = new SomeEntity(3, "e33"); Set aSet = new HashSet(); // aSet.add(e0.getDTO()); aSet.add(e1.getDTO()); aSet.add(e2.getDTO()); aSet.add(e3.getDTO()); aSet.add(e33.getDTO()); System.out.println("set size: " + aSet.size()); System.out.println("set:"); for (SomeEntity.SomeEntityId seId : aSet) { SomeEntity se = seId.getLink(); System.out.println("entity: " + se.getData()); } } }

I even could suggest you to add it to entities code generation in such tools as Hibernate Tools. I would also like to mention also that SomeEntityId object could be stored in transient field of an entity. Comments are welcome.

Advertisement

Author: Artem's Blog

Working on software and more...

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: