Hibernate 物件识别
Java而言,要物件是否同一物件有方式,一是根物件是否有同的位置定,在Java法中就是透== 算比,是Java所定的物件(Object identity),一是根equals()、hasCode()中的定,是Java所定的物件相等(Object equality)。
- 物件先探第一Java的方式在Hibernate中注意的地方,在Hibernate中,如果是在同一session中根相同查所得到的相同 料,它有相同的Java,的例子明:?
Session session = sessions.openSession();
Object obj1 = session.load(User.class, new Integer(1));
Object obj2 = session.load(User.class, new Integer(1));
session.close();
System.out.println(obj1 == obj2);
上面程式片段示true的果,表示obj1obj2是考至同一物件,但如果是以下的情示false:?
Session session1 = sessions.openSession();?
Object obj1 = session1.load(User.class, new?new Integer(1));?
session1.close();?
Session session2 = sessions.openSession();?
Object obj2 = session2.load(User.class,?new Integer(1));?
session2.close();?
System.out.println(obj1 == obj2);
原因可以考?介快取(Session Level)?。
用程式中基於效能的原因,不在一使用者的操作段,持始Session,物件持在 Persistence,Hibernate不保不同所取得的料物件,其是否考至的同一位置,使用==比物件的料是否代 表料中的同一料是不可 行的。
?
- 物件相等再物件相等的,在Java程式中要比物件是否相同,透equals()方法,而Object的 equals()本身是比物件的考,如果您要比物件的料容是否相同,您必作 equals()hashCode(),最的作方式,是在equals()中,物件的每性逐一加以比是否相同,之by value equality。
- 料一下Hibernate中料,料而言,其一料唯一性的方式是根主值,如果手上有份料,它有同的主值,它在料中代表同一 位的料。
由於主值是料中的料唯一方式,因此Hibernate中的料物件是否於一位料,就是根主值的物件 性(identifier property),Hibernate物件的性,必要,您可以性的setter方法定private,以避免程式中遭到 修改,您可以藉由Session的getIdentifier()方法取得物件的性值。
如果要合equals()、hashCode()作物件相等,一根料的性的作方式,是透性的getter方法取得物件的性值加以比, 例如若id的型是String,一作的例子如下:?
public class User {?
? ? ....?
? ? public boolean equals(Object o) {?
? ? ? ? if(this == o) return true;?
? ? ? ? if(id == null || !(o instanceof User)) return false;?
? ? ? ? final User user == (User) o;?
? ? ? ? return this.id.equals(user.getId());?
? ? }?
? ? public int hashCode() {?
? ? ? ? return id == null ? System.identityHashCode(this) : id.hashcode();?
? ? }?
}
例子取自於Hibernate in Action第123的例,之database identity equality,然而要注意的是,因一物件被new出而有save(),它不被予id值,如果您在物件存前,可能就有需求比物件的相等性,就不用 方法,例如物件若被加入Set物件之中,物件在被存至料前後,在Set中的判有所不同,致明明是同一物件,使得程式出不同的行。?
好的方式是根商值(Business key)作equals()hashCode(),之business key equality,在?Hibernate 官方考手?中了一例子:?
public class Cat {?
? ? ...?
? ? public boolean equals(Object other) {?
? ? ? ? if (this == other) return true;?
? ? ? ? if (!(other instanceof Cat)) return false;?
? ? ? ? final Cat cat = (Cat) other;?
? ? ? ? if (!getName().equals(cat.getName())) return false;?
? ? ? ? if (!getBirthday().equals(cat.getBirthday())) return false;?
? ? ? ? return true;?
? ? }?
? ? public int hashCode() {?
? ? ? ? int result;?
? ? ? ? result = getName().hashCode();?
? ? ? ? result = 29 * result + getBirthday().hashCode();?
? ? ? ? return result;?
? ? }?
}
by value equality的作方式似,但根性的不同是不再比所有的性,而是只比商,商 是一性或多性的合,每具有相同料的物件,商的合也是唯一的,商的挑可以找那些不null、 immutable或很少改且具有唯一性的性(例如位中UNIQUE的性),用性作商性之一也是一。
意的,可以使用org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.HashCodeBuilder助定equals()hashCode(), 例如:
package onlyfun.caterpillar;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class User {
? ? ?....
??? public boolean equals(Object obj) {
??????? if(obj == this) {
??????????? return true;
??????? }
????????
??????? if(!(obj instanceof User)) {
??????????? return false;
??????? }
????????
??????? User user = (User) obj;
??????? return new EqualsBuilder()
???????????????? .append(this.name, user.getName())
???????????????? .append(this.phone, user.getPhone())
???????????????? .isEquals();
????????
??? }
????
??? public int hashCode() {
??????? return new HashCodeBuilder()
???????????????? .append(this.name)
???????????????? .append(this.phone)
???????????????? .toHashCode();
??? }
}