A Concise solution for hashCode() and equals() implementations

23 06 2009

Currently, I was working on improving code quality. Some of the violations were due to the code generated by eclipse for hashCode() and equals() methods in the domain model classes. I was thinking on writing a builder classes for these methods, later on I just came across the Apache Commons Lang builder classes. It was even better than I imagined:)

Actually, the Apache Commons org.apache.commons.lang.builder package contains builder classes to help implement methods like equals() , hashCode() , compareTo(), and toString().. They are implemented to follow rules from in Effective Java , by Joshua Bloch

Considering clarity, readability and maintainability of the code, they are very concise and consistent solution.

The EqualsBuilder
Here is the sample usage of EqualsBuilder from API docs.

public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MyClass)) {
return false;
}
MyClass other= (MyClass) obj;
return new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(field1, other.field1)
.append(field2, other.field2)
.append(field3, other.field3)
.isEquals();
}

It is good to be carefull with isEquals() method, it is a common mistake to use equals() of the EqualsBuilder instead of isEquals().

The HashCodeBuilder
Here is the sample usage of HashCodeBuilder:

public int hashCode() {
return new HashCodeBuilder().
append(field1).
append(field2).
append(field3).
toHashCode();
}

It is good to be careful again with toHashCode() method, it is a common mistake to use hashCode() of the HashCodeBuilder instead of toHashCode().

Alternatively, you can use the reflection-based static methods:

public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}

However, I think reflection implementations are not good for a real project: They are potentially much slower and it is very important for domain model, the fields icluded in these methods should be carefully and intentionally selected considering the implication on the model.





Optimistic Locking and Versioning in Hibernate

16 05 2009

What is optimistic locking?

Optimistic locking is a method used to prevent simultaneously access problem on the same entity for change, which does not lock on the database level, in order to maintain the correct data.

For example, if two user wants to update same entity in different transactions, when first one saves and then second one saves without getting updates from the first user’s change, who will be the winner?

Most of the web applications, like ours, has such cases: Two users retrieve and modify a data on the page, then first user saves the data a transcation and then second user modifies and saves the data in an another transacion. Here are 3 alternatives:
1. Last commit wins : Both updates are performed, the second user overwrites without seeing the first user changes and without any error message
2. First commit wins : (Optimistic Locking) The update is performed, but second user gets error message, requiring restart of the processes on the first users changes.

3. Merge conflicting update : The second user are prompted to merge changes.

Automatic Versioning

Hibernate provides automatic versioning for options 2 and 3, using a version field managed by hibernate.

Versioning with integer version

public class MyClass {
...
private int version;
...
}


<class name="MyClass">
<id ...>
<version name="version" column="VERSION" access="field">
...
</class>

Versioning with timestamp

public class MyClass {
...
private int lastModifyDataTime;
...
}


<class name="MyClass">
<id ...>
<timestamp name="lastModifyDataTime" column="LAST_MODIFIY_DATE_TIME" access="field">
...
</class>

Automatic versioning is handled by hibernate, you don’t need to update versions/timestamps.
Considering the example mentioned above, when second user saves, hibernate finds this user is working on the stale data and throws StaleObjectException.

You can catch this exception, and rethrow your own exception. By the way, if you’re using Hibernate with Spring, this exeception is wrapped with HibernateOptimisticLockingFailureException.

One more point, you should be aware of that hibernate ignores the versioning when getting object and updating fields and then version are in the same session.





User access to another schema in Oracle: Alternative to public synonyms

26 03 2009

Consider that there are 2 users in your database having their own schemas, but second user having less permission is required to work on the first schema. Possible solutions :

1 . To  create public/private synonyms

2. Use schema name in the queries.

3. Modify user session to point the first schema. Create a trigger on login.

CREATE OR REPLACE TRIGGER &app_user..APP_USER_LOGON AFTER LOGON ON &app_user..SCHEMA DECLARE

BEGIN

            EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = '|| UPPER('&owner_user');

   EXCEPTION

     WHEN OTHERS THEN raise_application_error(-20001, 'Error: ' || SQLERRM );

END ;




Spring Security: Authenticate user on LDAP without manager/admin user

26 03 2009

In my previou post on spring security with LDAP, I had used a manager/admin user to authenticate a user.

You can use the following code to authenticate the user directly, without manager/admin user:

<ldap-server id="ldapServer" url="ldap://ldapserver:port"/>

  <beans:bean id="bindAuthenticator" class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
    <beans:constructor-arg ref="ldapServer" />
    <beans:property name="userDnPatterns">
      <beans:list>
        <beans:value>CN={0},ou=Users,dc=example,dc=com</beans:value>
      </beans:list>
    </beans:property>
  </beans:bean>




Spring Security : Use Ldap for authentication, and database for authorities

12 03 2009

If you need to use Ldap for authentication and database /repository for authorization with spring security, here is a sample:

LDAP authenticator configuration

<ldap-server id="appLdapServer" url="ldap://ldapserver:port/dc=example,dc=com" manager-dn="uid=admin,ou=system" manager-password="your-pwd" />

<beans:bean id="companyLdapAuthProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
  <custom-authentication-provider />
  <beans:constructor-arg>
    <beans:bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
      <beans:constructor-arg ref="appLdapServer"/>
      <beans:property name="userDnPatterns">
        <beans:list><beans:value>uid={0},ou=Users</beans:value></beans:list>
      </beans:property>
    </beans:bean>
  </beans:constructor-arg>
  <beans:constructor-arg>
    <beans:bean class="com.mycompany.web.security.MyAuthoritiesPopulator">
      <beans:constructor-arg ref="myUserServiceBean"/>
    </beans:bean>
  </beans:constructor-arg>
</beans:bean>

Authorities populator:

public class MyAuthoritiesPopulator implements LdapAuthoritiesPopulator {

	private MyUserService userService;

    public MyAuthoritiesPopulator(MyUserService userService){
       this.userService = userService;
    }

	@Override
	public GrantedAuthority[] getGrantedAuthorities(DirContextOperations userData, String username) {
		Set userPerms = new HashSet();

        //get users permissions from service
		Set permissions = userService.getPermissions(username);

		for (MyPermission perm : permissions) {
				userPerms.add(new GrantedAuthorityImpl(perm.getName()));
		}
		return userPerms.toArray(new GrantedAuthority[userPerms.size()] );
	}
}




Return dynamic result from mock with Mockito

4 03 2009

Sometimes you need to stub a class only for a method and you may need to add some behavior to that stubbed mehod like get a value from a map and return it.
Instead of just returning an object for the stubbed method like:

when(mock.aMethod(anyString())).thenReturn("a static result");

you can return a dynamic result by using stubbing with callbacks feature of Mockito.

when(mock.aMethod(anyString())).thenAnswer(new Answer<MyObject>() {
     MyObject answer(InvocationOnMock invocation) {
         Object[] args = invocation.getArguments();         
         //you can do some stuff using args
         return ...;
     }
 });

In answer method you can access the mocked object itself :

Object mock = invocation.getMock();

By the way, this brings a bit complexity to your test. If you don’t really need it, do not use it. 
Don’t forget simplicity.





Hibernate inverse

9 07 2008

I have seen that many people have a confusion with Hibernate’s inverse keyword. Maybe, the term itself is a bit confusing.

The keyword “inverse” indicates which end of a relationship should be ignored. inverse=true means that this side is the inverse side, that is, this side is ignored. inverse=false means that this side is not inverse, that is, this side is the owner of the relationship.

Actually, to decide inverse value, you should think about what you want to do in parent-child relationship. If your parent class contains child list and child class has a reference to parent, and you want the parent to have the responsibility of the relation, i.e, save, delete, etc. operations, then you need to set  inverse=false at the child list property in the parent’s mapping file.





Blob Objects With Spring and Hibernate

6 06 2008

You have a stream objects, i.e files , and you want to save them to the database using Hibernate and Spring.

First of all, I suggest to create a different object only for saving content. Let’s sayyou have files to save:

public class MyFileContent extends Entity {

  private InputStream content;

  MyFileContent () {
  }

  public MyFileContent(InputStream content) {
   this.content = content;
  }

  public InputStream getContent() {
    return content;
  }

  private void setContent(InputStream content) {
    this.content = content;
   }
}

Here Entity is just a base class including an id, and getter and setter methods for id.

Here your Hibernate user type for blobs.

import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.orm.hibernate3.support.AbstractLobType;

public class BlobUserType extends AbstractLobType {

 public int[] sqlTypes() {
   return new int[] { Types.BLOB };
 }

 public Class returnedClass() {
   return InputStream.class;
 }

 protected Object nullSafeGetInternal(ResultSet rs, String[] names, Object owner, LobHandler lobHandler)
  throws SQLException, HibernateException {
   return lobHandler.getBlobAsBinaryStream(rs, names[0]);
 }

 protected void nullSafeSetInternal(PreparedStatement ps, int index, Object value, LobCreator lobCreator)
  throws SQLException, HibernateException {
   if (value != null) {
    lobCreator.setBlobAsBinaryStream(ps, index, (InputStream) value, -1);
   } else {
    lobCreator.setBlobAsBytes(ps, index, null);
   }
 }
}

And here, your hibernate mappping for MyFileContent class.

<class name="MyFileContent" table="MY_FILE_CONTENT">
 <id name="id" column="ID" type="java.lang.Long" unsaved-value="null">
 <generator class="sequence">
 <param name="sequence">S_MY_FILE_CONTENT</param>
 </generator>
 </id>
 <property name="content" column="CONTENT" type="BlobUserType"/>
</class>

Here, hibernate configuration possibly in your HibernateContext.xml

 <bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />

 <!-- Hibernate SessionFactory -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" ..>
   <property name="lobHandler" ref="defaultLobHandler"/>
    ...
 </bean>

For Oracle and Websphere; you need to use this lob handler definition instead of defaultLobHandler. Because of differences in Oracle’s Blob objects.

 <bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler" >
   <property name="nativeJdbcExtractor" >
       <bean class="org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor"/>
   </property>
 </bean>

And finally use it :

InputStream inputStream = ...;
MyFileContent fileContent = new StoredFile(inputStream);
myRepository.save(fileContent );

Don’t forget to write a test:)





A Solution to Hierarcy Cycle Problem with JSON: JSON Filter

6 06 2008

When you have a cycle in your domain model, beacuse sometimes you realy need it*, then with Spring JsonView, indeed you may have same problem in different cases, while converting Java objects to JSON objects, you can get en error :

net.sf.json.JSONException: There is a cycle in the hierarchy!

with a following unusefull stack trace:)

First of all, think carefully fi you really do need this cycle in the dependency. If you don’t, remove it.
If you do, the you can use, JSON filters.

I will give an example code to show it. In the code, resulting JSON object will contain only id, name and description fields and values of the objects.

     JsonConfig config = new JsonConfig();
     config.setJsonPropertyFilter(new PropertyFilter() {
        public boolean apply(Object source, String name, Object value) {
              if ("name".equals(name) || "description".equals(name) || "id".equals(name)) {
                  return false;
              }
              return true;
           }
       });
       List jsonObjects = new ArrayList();
       for (Object object : objects) {
           jsonObjects.add(JSONSerializer.toJSON(object, config));
       }
     //Here you have jsonObjects, do whatever you need.
      ...

This is a sample code. It depends on you how to use this in a proper way! :)

* Consider, you have an class X with composition Y, and in Y class, if you need all Xs referenced by Y, then you will probably have a property containing list of X. Then you have cycle! For example, Employee works on a Department, so Employee has a composition with Department, in Department you need all employees workin in this department.





Highlight Selected Menu For Current Page Using SiteMesh

30 05 2008

In my previous post, Dynamically Load Menus with SiteMesh, I described how to load menus dynamically based on the variable in the pages. Here, to highlight last selected menu (which means current menu item) we can use same thing.

This time the variables we specify in every page will be name for the menu items.
And instead of include jsp page in the previous post, we need to set menu items like this :

<li>
   <a class="${currentMenu == 'abc_menu' ? 'selected':''}"
       title="Abc" href="abc.html">Abc</a>
</li>

Here, for every menu item, it is needed to specify class decision. And do not forget to add css style for selected.