Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Friday, April 3, 2009

Generic Data Access Objects with Pagnation under Spring and Hibernate Framework

Page.java
import java.util.List;

public class Page<T> {
private List<T> rowsInPage;
private int pageSize;
private int pageNo;
private int totalRows;

/**
*
* @param pageNo
* @param pageSize
* @param rowsInPage
* @param totalRows
*/
public Page(int pageNo, int pageSize, List<T> rowsInPage, int totalRows) {
if(pageSize > 0){
this.pageNo = (pageNo > 0) ? pageNo : 1;
this.pageSize = pageSize;
this.rowsInPage = rowsInPage;
this.totalRows = totalRows;
}else if(pageSize == 0){
this.pageNo = 0;
this.pageSize = 0;
this.rowsInPage = null;
this.totalRows = 0;
}else{
this.pageNo = 1;
this.pageSize = -1;
this.rowsInPage = rowsInPage;
this.totalRows = -1;
}
}

/**
*
* @return
*/
public boolean hasNext() {
return getPages() > pageNo;
}

/**
*
* @return
*/
public boolean hasPrevious() {
return pageNo > 1;
}

/**
*
* @return
*/
public List<T> getRowsInPage() {
return rowsInPage;
}

/**
*
* @return
*/
public int getPageSize() {
return pageSize;
}

/**
*
* @return
*/
public int getPageNo() {
return pageNo;
}

/**
*
* @return
*/
public int getTotalRows() {
return totalRows;
}

/**
*
* @return
*/
public int getPages() {
if(totalRows > 0)
return (totalRows%pageSize == 0) ? totalRows / pageSize : totalRows / pageSize + 1;
else if(totalRows == 0)
return 0;
else
return 1;
}
}


GenericDAO.java
import java.io.Serializable;
import org.hibernate.criterion.Order;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.aais.core.utils.Page;

@Transactional(rollbackFor=Exception.class)
public interface GenericDAO<T, ID extends Serializable> {

/**
*
* @param id
* @param lock
* @return
*/
@Transactional(readOnly=true)
public T findById(ID id, boolean lock);

/**
*
* @param pageNo
* @param pageSize
* @param order
* @return
*/
@Transactional(readOnly=true)
public Page<T> findAll(int pageNo, int pageSize, Order order);

/**
*
* @param pageNo
* @param pageSize
* @param exampleInstance
* @param order
* @param excludeProperty
* @return
*/
@Transactional(readOnly=true)
public Page<T> findByExample(int pageNo, int pageSize, T exampleInstance, Order order, String[] excludeProperty);

/**
*
* @param pageNo
* @param pageSize
* @param queryName
* @param paramNames
* @param values
* @return
*/
@Transactional(readOnly=true)
public Page<T> findByHQL(int pageNo, int pageSize, String queryName, String[] paramNames, Object[] values);

/**
*
* @param entity
* @return
*/
@Transactional(propagation=Propagation.REQUIRED)
public T saveOrUpdate(T entity);

/**
*
* @param entity
*/
@Transactional(propagation=Propagation.REQUIRED)
public void delete(T entity);
}


GenericDAOHibernateImpl.java
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.aais.core.dao.GenericDAO;
import com.aais.core.utils.Page;

public abstract class GenericDAOHibernateImpl<T, ID extends Serializable> extends HibernateDaoSupport implements GenericDAO<T, ID> {

private Class<T> persistentClass;
private final static Log logger = LogFactory.getLog(GenericDAOHibernateImpl.class);

/**
*
*/
@SuppressWarnings("unchecked")
public GenericDAOHibernateImpl() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

/**
*
* @return
*/
public Class<T> getPersistentClass() {
return persistentClass;
}

/**
* (pageNo > 0 && pageSize > 0) paginate
* (pageNo < 0 && pageSize < 0) don't paginate
*/
public Page<T> findAll(int pageNo, int pageSize, Order order) {
return findByCriteria(pageNo, pageSize, order, (Criterion[])null);
}

/**
* (pageNo > 0 && pageSize > 0) paginate
* (pageNo < 0 && pageSize < 0) don't paginate
*/
@SuppressWarnings("unchecked")
protected Page<T> findByCriteria(int pageNo, int pageSize, Order order, Criterion...criterion) {
Criteria crit = getCriteria();
if(criterion != null){
for (Criterion c : criterion) {
crit.add(c);
}
}
if(order != null)
crit.addOrder(order);
int rowCount = 0;
if(pageSize > 0){
rowCount = (Integer) ((Criteria) crit.setProjection(Projections.rowCount())).uniqueResult();
crit.setProjection(null);
if(pageNo < 1)
pageNo = 1;
((Criteria) crit).setFirstResult((pageNo - 1) * pageSize);
((Criteria) crit).setMaxResults(pageSize);
if(pageSize > rowCount)
pageSize = rowCount;
}
crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List<T> list = crit.list();
return new Page<T>(pageNo, pageSize, list, rowCount);
}

/**
*
* @return
*/
protected Criteria getCriteria(){
Criteria crit = this.getSession().createCriteria(getPersistentClass());
return crit;
}

/**
* (pageNo > 0 && pageSize > 0) paginate
* (pageNo < 0 && pageSize < 0) don't paginate
*/
@SuppressWarnings("unchecked")
protected Page<T> findByCriteria(int pageNo, int pageSize, Criteria crit, Order order){
if(order != null)
crit.addOrder(order);
int rowCount = 0;
if(pageSize > 0){
rowCount = (Integer) ((Criteria) crit.setProjection(Projections.rowCount())).uniqueResult();
crit.setProjection(null);
if(pageNo < 1)
pageNo = 1;
((Criteria) crit).setFirstResult((pageNo - 1) * pageSize);
((Criteria) crit).setMaxResults(pageSize);
if(pageSize > rowCount)
pageSize = rowCount;
}
crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List<T> list = crit.list();
return new Page<T>(pageNo, pageSize, list, rowCount);
}

/**
* (pageNo > 0 && pageSize > 0) paginate
* (pageNo < 0 && pageSize < 0) don't paginate
*/
@SuppressWarnings("unchecked")
public Page<T> findByExample(int pageNo, int pageSize, T exampleInstance, Order order, String[] excludeProperty) {
Criteria crit = getCriteria();
Example example = Example.create(exampleInstance).enableLike();
if(excludeProperty != null){
for (String exclude : excludeProperty) {
example.excludeProperty(exclude);
}
}
crit.add(example);
if(order != null)
crit.addOrder(order);
int rowCount = 0;
if(pageSize > 0){
rowCount = (Integer) ((Criteria) crit.setProjection(Projections.rowCount())).uniqueResult();
crit.setProjection(null);
if(pageNo < 1)
pageNo = 1;
((Criteria) crit).setFirstResult((pageNo - 1) * pageSize);
((Criteria) crit).setMaxResults(pageSize);
if(pageSize > rowCount)
pageSize = rowCount;
}
crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List<T> list = crit.list();
return new Page<T>(pageNo, pageSize, list, rowCount);
}

/**
*
*/
public T findById(ID id, boolean lock) {
T entity = null;
if (lock)
entity = (T) getHibernateTemplate().get(getPersistentClass(), id, LockMode.UPGRADE);
else
entity = (T) getHibernateTemplate().get(getPersistentClass(), id);
if(entity == null){
logger.warn("Could not find out " + getPersistentClass().getName() + " instance with id=" + id);
}else{
if(logger.isDebugEnabled())
logger.debug("Getting "+getPersistentClass().getName()+" instance with id: " + id);
}
return entity;
}

/**
*
* @param queryName
* @param paramNames
* @param values
* @return
*/
private Query createQuery(String queryName, String[] paramNames, Object[] values) {
Query query = getSession().getNamedQuery(queryName);
query.setCacheable(true);
if ((paramNames != null) && (values != null)) {
for (int i = 0; i < paramNames.length; i++) {
query.setParameter(paramNames[i], values[i]);
}
}
return query;
}

/**
* (pageNo > 0 && pageSize > 0) paginate
* (pageNo < 0 && pageSize < 0) don't paginate
* don't use for full table paginate, that would be low efficency
*/
@SuppressWarnings("unchecked")
public Page<T> findByHQL(int pageNo, int pageSize, String queryName, String[] paramNames, Object[] values){
long rowCount = 0;
Query query = createQuery(queryName, paramNames, values);
if(pageSize > 0){
rowCount = ((Long)getRowCountByHQL(appendRowCountHQL(queryName), paramNames, values)).longValue();
if(pageNo < 1)
pageNo = 1;
if(pageSize > rowCount)
pageSize = (int)rowCount;
query.setFirstResult((pageNo - 1) * pageSize);
query.setMaxResults(pageSize);
}
List<T> list = query.list();
return new Page<T>(pageNo, pageSize, list, (int)rowCount);
}

/**
*
* @param queryName
* @return
*/
private String appendRowCountHQL(String queryName){
return queryName + ".Count";
}

/**
*
* @param queryName
* @param paramNames
* @param values
* @return
*/
@SuppressWarnings("unchecked")
private Object getRowCountByHQL(final String queryName, final String[] paramNames, final Object[] values) {
return ((Object) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Query query = createQuery(queryName, paramNames, values);
if (paramNames != null && values != null && paramNames.length == values.length) {
for (int i = 0, max = paramNames.length; i < max; i++) {
query.setParameter(paramNames[i], values[i]);
}
}
return query.uniqueResult();
}
}));
}


/**
*
*/
public T saveOrUpdate(T entity) throws DataIntegrityViolationException{
getHibernateTemplate().saveOrUpdate(entity);
return entity;
}

/**
*
*/
public void delete(T entity) {
getHibernateTemplate().delete(entity);
}
}

Thursday, April 2, 2009

Unit Testing Sample with Spring and JUnit Annotations

package test.com.one.dao.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.one.dao.CustomerDAO;
import com.one.model.Customer;

@ContextConfiguration(locations={"/applicationContext.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class CustomerDAOHibernateImplTests extends AbstractTransactionalJUnit4SpringContextTests{

@Autowired
private CustomerDAO customerDAO;

@Before
public void setup(){

}

@After
public void clean(){

}

@Test
public void testCRUD(){
Customer customer = new Customer();
customer.setCustomerFirstName("firstName");
customer.setCustomerLastName("lastName");
customer.setEmailAddr("email");
customer.setCreatedOn(new Date());
customer.setUpdatedOn(new Date());
customerDAO.saveOrUpdateCustomer(customer);
Assert.assertNotNull(customer.getCustomerId());
Assert.assertTrue(customer.getCustomerId().intValue() > 0);
customer = (Customer) customerDAO.getCustomerByCustomerId(customer.getCustomerId());
Assert.assertNotNull(customer);
Assert.assertEquals(customer.getCustomerFirstName(), "firstName");
Assert.assertEquals(customer.getCustomerLastName(), "lastName");
Assert.assertEquals(customer.getEmailAddr(), "email");
customerDAO.deleteCustomer(customer);
customer = (Customer) customerDAO.getCustomerByCustomerId(customer.getCustomerId());
Assert.assertNull(customer);
}

@Test
public void testGetCustomersByDateRange(){
Customer customer = new Customer();
customer.setCustomerFirstName("firstName");
customer.setCustomerLastName("lastName");
customer.setEmailAddr("email");
customer.setCreatedOn(new Date());
customer.setUpdatedOn(new Date());
customerDAO.saveOrUpdateCustomer(customer);
Assert.assertNotNull(customer.getCustomerId());
Assert.assertTrue(customer.getCustomerId().intValue() > 0);
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_YEAR, -1);
Date from = c.getTime();
c.add(Calendar.DAY_OF_YEAR, +2);
Date to = c.getTime();
List list = customerDAO.getCustomersByDateRange(from, to);
Assert.assertNotNull(list);
Assert.assertTrue(list.size() > 0);
}

@Ignore
public void testGetCustomerByFirstnameAndLastnameAndEmail(){
Customer customer = new Customer();
customer.setCustomerFirstName("firstName");
customer.setCustomerLastName("lastName");
customer.setEmailAddr("email");
customer.setCreatedOn(new Date());
customer.setUpdatedOn(new Date());
customerDAO.saveOrUpdateCustomer(customer);
Assert.assertNotNull(customer.getCustomerId());
Assert.assertTrue(customer.getCustomerId().intValue() > 0);
customer = (Customer) customerDAO.getCustomerByFirstnameAndLastnameAndEmail("firstName", "lastName", "email");
Assert.assertNotNull(customer);
Assert.assertEquals(customer.getCustomerFirstName(), "firstName");
Assert.assertEquals(customer.getCustomerLastName(), "lastName");
Assert.assertEquals(customer.getEmailAddr(), "email");
}

}

Monday, November 17, 2008

Integrated BlazeDS with Spring Framework

Spring is one of the most popular Java frameworks. The foundation of the Spring framework is a lightweight component container that implements the Inversion of Control (IoC) pattern.
Using an IoC container, components don't instantiate or even look up their dependencies (the objects they work with). The container is responsible for injecting those dependencies when it creates the components (hence the term "Dependency Injection" also used to describe this pattern).
The result is looser coupling between components. The Spring IoC container has proven to be a solid foundation for building robust enterprise applications. The components managed by the Spring IoC container are called Spring beans.

step by step:

1. Follow this article to create a basic blazeds-based java project.
2. Download spring framework and put the spring.jar into the blazeds-based java project.
3. Download flex-spring.zip and unzip it and put the SpringFactory.java to your source code folder. don't fotget to adjust the package name according to your package path.
4. Register the Spring factory on your services-config.xml.
5. Create applicationContext.xml in /WEB-INF and register Spring beans.
6. Update your remoting-config.xml.
7. Update your web.xml.
8. Create your flex app and new remoteObject to call java module.

For another new way to integrate spring to blazeds, pls go to Using Spring BlazeDS Integration 1.0.0.M1 .

sample code:
blazeds-spring-server-tutorial.rar and blazeds-spring-client-tutorial.rar , enjoy it.