Tasklist Task object

  • When using hibernate with objects you have to consider what might happen if an object representing a database record is fetched twice by hibernate and then compared, the comparison should return true but a straight object comparison will return false. To keep this from causing problems we have to create a set of comparison function in our value object (or the implementation of the value object).
  • At a minimum, you will need to create functions to handle equals and hashCode. It is a good idea to also create compareTo and toString functions.
  • NOTE: General instructions for creating these functions are available
  • For the tasklist tool example we will use the Apache commons-lang package since performance is not an issue
    We will be adding this code to the TaskImpl.java value object implementation


  1. Adding the commons-lang dependency to your project.xml
    1. Add the following to the dependencies block of your project.xml file to include the commons-lang:
      <dependency>
      	<groupId>commons-lang</groupId>
      	<artifactId>commons-lang</artifactId>
      	<version>${sakai.commons.lang.version}</version>
      </dependency>
      
      • The commons-lang package is included in shared/lib by Sakai itself so you do not need to package it in your tool war file (hence there is no <war.bundle>true</war.bundle>)
      • Do not specify a version, use the version that Sakai is placing in the shared/lib by using the property (sakai.commons.lang.version) as shown above
  2. Using the lang functions in your object or object implementation code - Apache commons-lang API
    Note: All code below should go in the object or object implementation
    1. Add the required imports
      import org.apache.commons.lang.builder.CompareToBuilder;
      import org.apache.commons.lang.builder.EqualsBuilder;
      import org.apache.commons.lang.builder.HashCodeBuilder;
      import org.apache.commons.lang.builder.ToStringBuilder;
      
    2. Create an equals function using the EqualsBuilder
      public boolean equals(Object obj) {
      	if (null == obj) return false;
      	if (obj instanceof org.sakaiproject.tool.mytool.MyObject == false) {
      		return false;
      	}
      	if (this == obj) { return true; }
      	org.sakaiproject.tool.mytool.MyObject castObj = (org.sakaiproject.tool.mytool.MyObject) obj;
      	return new EqualsBuilder()
      		.append(this.getId(), castObj.getId())
      		.isEquals();
      }
      
      • This simple example only compares the id values of the 2 objects, however you could compare many values by doing something like this:
        return new EqualsBuilder()
             .append(this.field1, castObj.getField1())
             .append(this.field2, castObj.getField2())
             .append(this.field3, castObj.getField3())
             .isEquals();
        
    3. Create a hashCode function using the HashCodeBuilder
      public int hashCode() {
      	// pick 2 hard-coded, odd, >0 ints as args
      	return new HashCodeBuilder(1, 31)
      		.append(this.id)
      		.toHashCode();
      }
      
      • Like the previous example, this only uses the id for creating the hashCode but you can easily append more properties
    4. Create a compareTo function using the CompareToBuilder
      public int compareTo(Object obj) {
      	org.sakaiproject.tool.mytool.MyObject castObj = (org.sakaiproject.tool.mytool.MyObject) obj;
      	return new CompareToBuilder()
      		.append(this.getId(), castObj.getId())
      		.toComparison();
      }
      
      • Like the previous examples, this only uses the id for comparison but you can easily append more properties
    5. Create a toString function using the ToStringBuilder
      public String toString() {
      	return new ToStringBuilder(this)
      		.append(this.id)
      		.toString();
      }
      
      • Like the previous examples, this only uses the id for string generation but you can easily append more properties
  3. Your object should now be comparable to objects of the same type that have the same data
    • A sample of an object which demostrates use of the commons-lang builders: TaskImpl.java
    • A sample of implemented functions using commons-lang:
      public boolean equals(Object obj) {
      	if (obj == null) return false;
      	if (obj instanceof Task == false) return false;
      	if (this == obj) return true;
      	Task castObj = (Task) obj;
      	return new EqualsBuilder()
      		.append(this.getId(), castObj.getId())
      		.append(this.getOwner(), castObj.getOwner())
      		.append(this.getSiteId(), castObj.getSiteId())
      		.isEquals();
      }
      
      public int hashCode() {
      	// pick 2 hard-coded, odd, >0 ints as args
      	return new HashCodeBuilder(1, 31)
      		.append(this.id)
      		.append(this.owner)
      		.append(this.siteId)
      		.toHashCode();
      }
      
      public int compareTo(Object obj) {
      	Task castObj = (Task) obj;
      	return new CompareToBuilder()
      		.append(this.getId(), castObj.getId())
      		.append(this.getOwner(), castObj.getOwner())
      		.toComparison();
      }
      
      public String toString() {
      	return new ToStringBuilder(this)
      		.append(this.id)
      		.append(this.owner)
      		.append(this.siteId)
      		.append(this.creationDate)
      		.append(this.task)
      		.toString();
      }