Enterprise Java Development@TOPIC@
hashCode()
Returns an int value to be used by hashtables to help store and locate
Must remain constant *unless* state that is used to derive value changes
Two objects resulting in equals(obj)=true must return same hashCode
Two objects resulting in same hashCode may result in equals(obj)=false - but may lead to inneficient access
equals()
Returns the boolean result of whether two objects are "equal"
Reflexive - this should always equal this
Symmetric - if x==y, then y==x
Transitive - if x==y and y==z, then x==z
Consistent - if x==y, then x will always equal y (unless state used changes)
Uses object instance to determine identity
Two instances with identical state will not be equal
Default implementation
Works for cases where you will only have a single instance representing a single object
Figure 59.1. Using Default Identity Methods
public class java.lang.Object {
...
public native int hashCode();
public boolean equals(java.lang.Object);
...
}
Use assigned database primary key as identity
Positives: unique value within table or possibly database
Negatives: automatically generated values not available until object persisted
Only an issue for auto-generated primary keys
Figure 59.2. Using Database Primary Key For Identity
@Entity
public abstract class Ship {
@Id
@GeneratedValue
protected int id;
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
try {
if (obj == null) { return false; }
if (this == obj) { return true; }
return id==((Ship)obj).id;
} catch (Exception ex) { return false; }
}
Using instanceId until database primary key assigned
Positives: able to compare objects in same persistent stage
Negatives:
Persisting object will break consistency rule (except that state really did change)
Cannot compare transient instances to persisted instances
Identity-based collections can get confused by inconsistent behavior
Figure 59.3. Switching Identity Schemes
@Override
public int hashCode() {
return id==0 ? super.hashCode() : id;
}
@Override
public boolean equals(Object obj) {
try {
if (obj == null) return false;
if (this == obj) { return true; }
return (id==0) ? super.equals(obj) : id==((Ship)obj).id;
} catch (Exception ex) { return false; }
}
Use unique business values to determine identity -- independent of database primary key
Positives: consistent state through persistence lifecycle of object
Negatives: may have trouble identifying unique properties within each object type
Figure 59.4. Switching Identity Schemes
@Override
public int hashCode() {
return (name==null ? 0 : name.hashCode()) +
(created==null ? 0 : (int)created.getTime());
}
@Override
public boolean equals(Object obj) {
try {
if (obj == null) { return false; }
if (this == obj) { return true; }
return name.equals(((ShipByBusinessId)obj).name) &&
created.getTime() == (((ShipByBusinessId)obj).created.getTime());
} catch (Exception ex) { return false; }
}
Collection
Bag, no specific collection ordering. Duplicates allowed.
List
Duplicates allowed. Order maintained by database using @SortKey("property ASC/DESC")
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn @OrderBy("number ASC") private List<Segment> segments;
Set
Unique value (object identity comes into play here). No specific order.
Map
Each object registered in collection with a property key using @MapKey("property")
@OneToMany @MapKey(name="position") @JoinColumn(name="LINEUP_ID") private Map<String, Position> positions;