Archive

Posts Tagged ‘Spring’

Quickstart series: Spring+Spring Security+Jersey+Hibernate

01/03/2012 3 comments

I’m starting the ‘quickstart series’ – the initial post will be about these four technologies, integrated and fully functional.

The project is built with Maven and Eclipse, sou you may be able to checkout it and import it on your Eclipse (or other environments compatible with Eclipse, like Netbeans).

It is configured with:

Spring and Spring Security 3.0.5
Jersey 1.9
Hibernate 3.4.0
JPA 1.0
MySQL 5.1

If you want a different configuration, feel free to modify it as you wish and, if you don’t mind, please take a few minutes to update the repository. By the way, it is https://github.com/alesaudate/kickstart-springjerseyhibernate. Feel free to clone it and have a bootstrap on your project.

Enjoy!

Categories: Uncategorized Tags: , , , , , , , ,

Quick Post: Integrating Spring and Jersey

02/02/2011 2 comments

When: When you need Spring to manage Jersey´s libraries, but still want to be free to develop your services using JAX-RS.

When not: If your team does not know REST, maybe it´s not a good idea to use it in development, because REST has its own culture – Uniform Interfaces, Hypermedia, the concept of Resource-Oriented, etc.

How:

BaseEntity.java

package com.alesaudate.domain;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;

import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;


@MappedSuperclass
public abstract class BaseEntity {
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	
	@Version
	private Long version;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Long getVersion() {
		return version;
	}

	public void setVersion(Long version) {
		this.version = version;
	}
	
	
	
	/**
	Validation code, that is valid for all subclasses.
	*/
	public void validate () throws ValidationException {
	
		ClassValidator validator = new ClassValidator(getClass());		
		
		InvalidValue[] invalidValues = validator.getInvalidValues(this);
		
		if (invalidValues != null && invalidValues.length > 0) {
			throw new ValidationException(buildValidationExceptionMessage(invalidValues));
		}
	}
	
	
	public String buildValidationExceptionMessage (InvalidValue[] invalidValues) {
		StringBuilder builder = new StringBuilder();
		
		for (InvalidValue value : invalidValues) {
			builder.append(value.toString()).append("\n");
		}
		
		return builder.toString();
	}
	
}


BaseService.java

package com.alesaudate.services;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alesaudate.domain.BaseEntity;
import com.alesaudate.domain.InvalidStateException;
import com.alesaudate.domain.Person;
import com.alesaudate.services.support.collections.Collection;



@Component
public abstract class BaseService<T extends BaseEntity> {
	
	
	@Autowired
	private HibernateTemplate hibernateTemplate;
	
	
	@Transactional
	public T createOnDatabase (T entity) throws InvalidStateException {
		entity.validate();
		getHibernateTemplate().persist(entity);
		return entity;
	}
	
	
	@POST
	@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
	public T create (T entity) throws InvalidStateException {
		return createOnDatabase(entity);
	}
	
	
	@Transactional
	public T updateOnDatabase (T entity) throws InvalidStateException {
		entity.validate();
		getHibernateTemplate().update(entity);
		return entity;
	}
	
	@PUT
	@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
	public T update (T entity) throws InvalidStateException  {
		return updateOnDatabase(entity);
	}
	
	
	@Transactional(readOnly=true)
	public T findOnDatabase (Long id) {
		
		DetachedCriteria criteria = DetachedCriteria.forClass(getManagedClass()).add(Restrictions.eq("id", id));
		List entities = getHibernateTemplate().findByCriteria(criteria);
		if (entities.isEmpty()) 
			return null;
		return (T)entities.get(0);
	}
	
	@GET
	@Path("{id}")
	@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
	public T find (@PathParam("id")Long id) {
		T entity = findOnDatabase(id);
		loadEntity(entity);
		return entity;
	}
	
	
	@Transactional(readOnly=true)
	public List<T > findAllFromDatabase () {
		
		DetachedCriteria criteria = DetachedCriteria.forClass(getManagedClass());
		List<T> all = getHibernateTemplate().findByCriteria(criteria);
		loadList(all);
		return all;
	}
	
	@GET	
	@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})	
	@Collection
	public List<T> findAll() {
		return findAllFromDatabase();
	}
	
	
	@Transactional
	public void deleteFromDatabase (T toDelete) {
		getHibernateTemplate().delete(toDelete);
	}
	
	

	@DELETE
	@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
	public void delete (T toDelete) {
		deleteFromDatabase(toDelete);
	}
	
	public abstract Class<? extends BaseEntity> getManagedClass();
	
	
	public abstract void loadEntity (T data);
	
	public abstract void loadList (java.util.Collection<T> data);
	
	
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
	
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

}

PersonService.java

package com.alesaudate.services;

import java.util.Collection;

import javax.ws.rs.Path;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alesaudate.domain.Address;
import com.alesaudate.domain.BaseEntity;
import com.alesaudate.domain.Person;




@Component
@Path("/person")
public class PersonService extends BaseService<Person>{

	@Override
	public Class<? extends BaseEntity> getManagedClass() {
		return Person.class;
	}

	@Override
	public void loadEntity(Person data) {
		//Load addresses
		data.getAddresses();
	}

	@Override
	@Transactional(propagation=Propagation.MANDATORY)
	public void loadList(Collection<Person> data) {
		for (Person p : data) {			
			getHibernateTemplate().find("select p.addresses from Person p");
			for (Address address : p.getAddresses()) {
				getHibernateTemplate().evict(address);
				address.makeXMLCompatible();
			}
			getHibernateTemplate().evict(p);
		}
		
	}

	
	
	
	
	
	
}

applicationContext.xml:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	

	<context:component-scan base-package="com.alesaudate.services" />

<!-- Other bean definitions... -->		


</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Architecture</display-name>
  
  <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>classpath:applicationContext.xml</param-value>
   </context-param>

 
   <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>
   <listener>
          <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
   </listener>

 <servlet>
 	<servlet-name>Jersey Servlet</servlet-name>
 	<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
 </servlet>
 
 <servlet-mapping>
 	<servlet-name>Jersey Servlet</servlet-name>
 	<url-pattern>/*</url-pattern>
 </servlet-mapping>
  
</web-app>

End.