Archive for the ‘Java Development’ Category

Learnings from the Past: Hibernate related Best Practices

Thursday, March 18th, 2010

Back to blogging after a gap of 8 months. I have been working on some cool optimization stuff related to Hibernate. Here is a brief summary of the best practices i have come across on this and past assignments involving Hibernate.

# Practice What? Why? How?
1 Use Lazy Load Don’t load objects until you need to use them. Queries involve lesser joins, so become faster By Using @Lazy annotation for simple attributes and LazyCollection for Collections
2 Use allocationSize>1 for Sequences Use an allocationSize value of 50 or 100 instead of the default allocationSize of 1 Avoids frequent db access to fetch next sequence value By using @allocationSize=50, Hibernate will generate the next sequence values for 50 invocations before hitting the db again.
3 Keep big character/byte fields in a seperate entity Seperate big fields like blob, clob, varchar(500), etc., into a seperate entity called <enityName>Details Avoids time spent in fetching data for these fields on listing screens which do not typically display this information By using a one-to-one mapping with the details object and keeping the direction of association from main->detail
4 Use Hibernate Caching Using Hibernate Second Level cache and Query cache to store frequently used objects/results Avoids hitting the db for frequently used information Turn on Hibernate Second level cache and Quey cache

Learnings from the past: Writing jMock Unit tests in 6 simple steps

Friday, July 17th, 2009

Do you ever come across a situation where your Unit test ends up testing more than what a unit is supposed to be?  Does your unit test end up looking more like an Integration test? Does it only run within a container? Does it depend on external things like records in a table, entries in ldap or data in some files? If your answer to any of the above questions is yes, then jMock could be the solution to your unit testing problem.

jMock is a library for testing Java code with mock objects. It sits on top of your existing unit testing framework (eg.Junit). It allows you to mock out interactions between objects hence preventing external dependencies.

You can write a jMock unit test using 6 simple steps:

  1. Initialize input:-  This is where you initialize all static data that will be used for the current unit test.
  2. Initialize mocks:- Mock out your external dependencies here.
  3. Setup expectations:- After you create the mock objects, you need to specify what interactions you are expecting to have with them. If the interactions dont happen as you expected, the test fails.
  4. Initialize subject:- Subject is the object that you are trying to unit test. You will create an instance of the object and initialize it here.
  5. Invoke Subject:- Call the method to be tested with static input.
  6. Assert:- Make sure output is as expected and all expectations set on the mocks have been satisfied.

Here is an example of how to go about using jMock:-
AccountService exposes a “getAccountInformation” method which we want to unti test. This method first validates the input, authenticates credentials with ldap and then fetches the account information from the database. It uses a DB accessor and ldap authenticator to do so. First lets look at the AccountService:

package com.amarphadke.jmockdemo.service;
 
import com.amarphadke.jmockdemo.accessor.Authenticator;
import com.amarphadke.jmockdemo.accessor.DataAccessor;
import com.amarphadke.jmockdemo.domain.Account;
import com.amarphadke.jmockdemo.exception.DomainException;
import com.amarphadke.jmockdemo.exception.ValidationException;
import com.amarphadke.jmockdemo.transport.AccountInformation;
import com.amarphadke.jmockdemo.transport.AccountInformationRequest;
 
public class AccountService {
	private DataAccessor dataAccessor;
	private Authenticator authenticator;
 
	public AccountService(DataAccessor dataAccessor, Authenticator authenticator) {
		super();
		this.dataAccessor = dataAccessor;
		this.authenticator = authenticator;
	}
 
	public AccountInformation getAccountInformation(
			AccountInformationRequest request) throws ValidationException, DomainException {
		validateInput(request);
		Account account = dataAccessor.fetchAccount(request.getAccountId());
		AccountInformation accountInformation = convertDomainObjectToTransportObject(account);
		return accountInformation;
	}
 
	private AccountInformation convertDomainObjectToTransportObject(Account account) {
		AccountInformation accountInformation = new AccountInformation(account
				.getAccountId(), account.getAccountType(), account
				.getLastAccessedDate(), account.getFirstName(), account
				.getLastName(), account.getBalance());
		return accountInformation;
	}
 
	private void validateInput(AccountInformationRequest request)
			throws ValidationException {
		if (request.getAccountId() <= 0) {
			throw new ValidationException(1, "Invalid Account Id");
		}
 
		if (request.getUsername() == null) {
			throw new ValidationException(2, "Invalid Username");
		}
 
		if (request.getPassword() == null) {
			throw new ValidationException(3, "Invalid Password");
		}
 
		if (!authenticator.isValidCredential(request.getAccountId(), request
				.getUsername(), request.getPassword())) {
			throw new ValidationException(4, "Invalid Credentails for Account");
		}
	}
}

Now, lets take a look at the unit test:

package com.amarphadke.jmockdemo.service;
 
import java.util.Calendar;
import java.util.Date;
 
import junit.framework.TestCase;
 
import org.jmock.Expectations;
import org.jmock.Mockery;
 
import com.amarphadke.jmockdemo.accessor.Authenticator;
import com.amarphadke.jmockdemo.accessor.DataAccessor;
import com.amarphadke.jmockdemo.domain.Account;
import com.amarphadke.jmockdemo.exception.DomainException;
import com.amarphadke.jmockdemo.exception.ValidationException;
import com.amarphadke.jmockdemo.service.AccountService;
import com.amarphadke.jmockdemo.transport.AccountInformation;
import com.amarphadke.jmockdemo.transport.AccountInformationRequest;
 
public class AccountServiceTest extends TestCase {
	private Mockery context = new Mockery();
 
	/*
	 * Test for AccountService.getAccountInformation(AccountInformationRequest)
	 * with valid input.
	 */
	public void testGetAccountInformationWithValidInput()
			throws ValidationException, DomainException {
		// Step 1: Initialize input
		final long accountId = 123456789;
		final String username = "jmockDemoUser";
		final String password = "encryptedPassword";
		String accountType = "Checking";
		Double balance = new Double(100000000.99);
		String firstName = "Richie";
		String lastName = "Rich";
		Date lastAccessedDate = Calendar.getInstance().getTime();
 
		final AccountInformationRequest request = new AccountInformationRequest(
				accountId, username, password);
		final Account account = new Account(accountId, accountType,
				lastAccessedDate, firstName, lastName, balance, null, null);
		final AccountInformation accountInformation = new AccountInformation(
				accountId, accountType, lastAccessedDate, firstName, lastName, balance);
 
		// Step 2: Initialize mocks
		final DataAccessor dataAccessor = context.mock(DataAccessor.class);
		final Authenticator authenticator = context.mock(Authenticator.class);
 
		// Step 3: Setup Expectations
		context.checking(new Expectations() {
			{
				oneOf(authenticator).isValidCredential(accountId, username, password);
				will(returnValue(true));
 
				oneOf(dataAccessor).fetchAccount(accountId);
				will(returnValue(account));
			}
		});
 
		// Step 4: Initialize Subject
		AccountService accountService = new AccountService(dataAccessor,
				authenticator);
 
		// Step 5: Invoke Subject
		AccountInformation actualAccountInformation = accountService
				.getAccountInformation(request);
 
		// Step 6: Assert
		assertEquals(accountInformation, actualAccountInformation);
		context.assertIsSatisfied();
	}
}

Complex Programs with Simple code?

Sunday, April 5th, 2009

Chessboard

After my last post, i was wondering if really complex programs/systems/applications could be written using simple, easy-to-understand code. Code that does not span more than 10 lines a method.

The most complex program that i could think of to experiment with was a Chess server – an app that would evaluate a position and suggest the “next best” move. This app would have a set of rules which would determine how good a position is. All possible “next moves” will be stored in a tree and evaluated on the position they end up with after ‘n’ moves. For more information->http://en.wikipedia.org/wiki/Computer_chess

I have created an open-source project on sourceforge.net for this activity->http://sourceforge.net/projects/javachessserver. What i have in there so far are the Chess domain objects, Rule interface, several skeleton rules and one concrete rule->CheckmateRule

I would be interested in knowing what you think about this project. If you are interested in joining this project and wish to explore this idea, i would be happy to include you.

Code quality and cyclomatic complexity

Saturday, February 21st, 2009

I recently came across this article on code quality and cyclomatic complexity. Found it interesting and so thought of sharing.
Do the following phrases sound familiar to you?  They surely sounded familiar to me.

Sure, it’s a bit confusing (at first), but look how extensible it is!!

It’s confusing to you because you obviously don’t understand patterns.