-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Projects don't follow the rules in the hibernate docs?
PostPosted: Thu Nov 26, 2015 9:16 am 
Newbie

Joined: Thu Nov 26, 2015 8:24 am
Posts: 1
Hi,

While analyzing some design rules with design tests for persistent classes, I discovered that 91% of a sample of 40 projects from GitHub don't follow the rules about the implementation of the equals/hashCode methods.

These rules are in the documentation of Hibernate (subsection 2.1.5 chapter 2). The first one states that the equals/hashCode methods must be implemented and the second one that their implementation must not access the identifying property. 66% of the projects violate the first rule and 25% violate the second one.

Do you think these software projects have latent bugs caused by the design rules violations or is the rule unnecessary? Don’t Hibernate devs consider the anomalies caused by design rules violations described on chapter 2 as errors?

There are also other rules that they aren't being followed. For more details about the experiment with others results, access: http://tacianosilva.github.io/designtests

Thanks in advance!

Taciano


Top
 Profile  
 
 Post subject: Re: Projects don't follow the rules in the hibernate docs?
PostPosted: Thu Nov 26, 2015 11:56 am 
Regular
Regular

Joined: Mon Oct 19, 2015 7:49 am
Posts: 61
Location: ChengDu China
Good question! Yes, you're right. The knowledge that often looks very simple actually are very difficult.
It's too difficult to give the perfect implementation for method "hashCode" and "equals" of non-final class! (For any language, not only java)

Let's discuss two issues: (1) and (2)

(1) For stable objects, there are 2 classic ways to implement equals

(A) Too lax way
Code:
@Override
public boolean equals(Object o) {
   if (this == o) return true;
   if (!(o instanceof MyClass)) return false;
   return this.x == this.x && this.y == this.y;
}

This way is too lax, suppose there are 2 classes: A and B, A is super class and B is derived class. It will cause "a.equals(b)" is true but "b.equals(a)" is false.
But it can handle the object proxy very well, so it's often used in the equals method of ORM entity class.

(B) Too strict way
Code:
@Override
public boolean equals(Object o) {
   if (this == o) return true;
   if (o == null || this.getClass() != o.getClass()) return false;
   return this.x == this.x && this.y == this.y;
}

This way is very strict, that's why it's the default generated code of IDE such as eclipse. But it can't used to handle the object proxy(Proxy is a popular technology, especially for ORM). For example:
Code:
public class MyProxy extends MyClass {
   private MyClass target;
   public MyProxy(MyClass target) { this.target = target; }
   @Override
   public int getX() { return this.target.getX(); }
   @Override
   public void setX(int x) { this.target.setX(x); }
   ...other methods such as getY and setY, hashCode...
   @Override
   public boolean equals(Object o) { return this.target.equals(o); }
}

This way will cause "new MyClass(3, 4).equals(new MyProxy(new MyClass(3, 4))" returns the wrong result "false", that's why I said this way is too strict.

(2) For data object, especially for ORM entity objects, hashCode is very hard to be implemented.
Code:
@Entity
public class MyEntity {
   @Column
   private String uniqueName;
   public String getUniqueName() { return this.uniqueName; }
   public void setUniqueName(String uniqueName) { this.uniqueName = uniqueName; }
   @Override
   public int hashCode() {
      return java.util.Objects.hashCode(this.uniqueName);
   }
   ...other methods...
}

This class uses the field "uniqueName" to calculate the hashCode, but don't forget the "uniqueName" can be changed by the method "setUniqueName" after the current object has been added into some HashSets or HashMaps, if it's changed, the set and maps retain this object will be broken, but it's very hard to guarantee no body will change an object which is retained by sets and maps.
This is called unstable class, ORM entity classes are often unstable classes, that's why the hashCode and equals method for ORM entity is harder to be implemented.

I've thought these problems for several years. all of them have been resolved in my framework
https://github.com/babyfish-ct/babyfish
.
For issue(1)
This framework supports new way to implement method "equals", it's neither too lax nor too strict, between (1.A) and (1.B) of this topic. Please see ${babyfish_dir}/demo/babyfishdemo-fundation/.../src/test/java/org/babyfishdemo/foundation/equality/clazz/PointEqualityTest.java to understand my solution.

For issue(2)
This framework supports new collection framework that does not require the method "hashCode" and "equals" of the object itself, but requires a 3rd-party rule, this new collection framework also supports "Unstable Collection Elements", If an unstable object has been added into some sets or added to some maps as key, it can still be changed by user, all the sets and maps depend on it will be adjusted automatiaclly when it's changed. Please see ${babyfish_dir}/demo/babyfishdemo-xcollection/src/test/java/org/babyfishdemo/xcollection/uce/UnstableCollectionElementsTest.java to understand my solution.

By the way, under the root directory, a file "fast-learn_zh_CN.docx" is very useful to know the whole framework very quickly but it's wrote by Chinese, English version will be added in one week, please wait :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.