Archive for the ‘ HowTo & Tutorial ’ Category

Retrieving Id field from JPA and Hibernate

quick code snippet to get the identifier field name for a given entity class from both hibernate and JPA 2.0 APIs.

for hibernate

public String getIdProperty(Class entityClass) {
String idProperty=sessionAccessor.getSessionFactory()
                                              .getClassMetadata(entityClass)
                                              .getIdentifierPropertyName();
return idProperty;
}

for JPA 2.0 metamodel API this method or to get value of id field see comment below

public String getIdProperty(Class entityClass) {
        String idProperty;
        Metamodel metamodel = getEntityManager().getMetamodel();
        EntityType entity = metamodel.entity(entityClass);
        Set<SingularAttribute> singularAttributes = entity.getSingularAttributes();
        for (SingularAttribute singularAttribute : singularAttributes) {
            if (singularAttribute.isId()){
                idProperty=singularAttribute.getName();
                break;
            }
        }
        if(idProperty==null)
            throw new RuntimeException("id field not found");
        return idProperty;
    }

to

JPA Criteria API by samples – Part-II

you can read first part from JPA Criteria API by samples – Part-I

some more examples with JPA criteria API

Simple Join query

        long category=200L;
        Query query = entityManager.createQuery("select s from OrderItem s " +
        		"where s.product.category=:cat");
        query.setParameter("cat", category);
        List<OrderItem> list = query.getResultList();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
        Root<OrderItem> from = criteriaQuery.from(OrderItem.class);
        Path<Object> path = from.join("product").get("category");

        CriteriaQuery<Object> select = criteriaQuery.select(from);
        select.where(criteriaBuilder.equal(path, category));

        TypedQuery<Object> typedQuery = entityManager.createQuery(select);
        List<Object> resultList = typedQuery.getResultList();
        assertEqualsList(list, resultList);

simple fetch join query

        long category=200L;
        Query query = entityManager.createQuery("select s from OrderItem s " +
        		"join fetch s.product where s.product.category=:cat");
        query.setParameter("cat", category);
        List<OrderItem> list = query.getResultList();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
        Root<OrderItem> from = criteriaQuery.from(OrderItem.class);
        Path<Object> path = from.join("product").get("category");

        from.fetch("product"); //FETCH product

        CriteriaQuery<Object> select = criteriaQuery.select(from);
        select.where(criteriaBuilder.equal(path, category));

        TypedQuery<Object> typedQuery = entityManager.createQuery(select);
        List<Object> resultList = typedQuery.getResultList();
        assertEqualsList(list, resultList);

subselect (subquery) join query

         Query query = entityManager.createQuery(
                "select s from OrderItem s join fetch s.product" +
                " where s.product.category in" +
                " (select sb.pbyte from SimpleBean sb where sb.pint>=30000)");

        List<OrderItem> list = query.getResultList();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
        Root<OrderItem> from = criteriaQuery.from(OrderItem.class);
        Path<Object> path = from.join("product").get("category");
        from.fetch("product");
        CriteriaQuery<Object> select = criteriaQuery.select(from);

        Subquery<SimpleBean> subquery = criteriaQuery.subquery(SimpleBean.class);
        Root fromSimpleBean = subquery.from(SimpleBean.class);
        subquery.select(fromSimpleBean.get("pbyte"));
        subquery.where(criteriaBuilder.ge(fromSimpleBean.get("pint"),30000));
        select.where(criteriaBuilder.in(path).value(subquery));

        TypedQuery<Object> typedQuery = entityManager.createQuery(select);
        List<Object> resultList = typedQuery.getResultList();
        assertEqualsList(list, resultList);

JPA Criteria API by samples – Part-I

In this post I try to explain jpa criteria API by simple example on a single entity.

Although examples are pretty much simple it will help you with finalized version of JPA 2.0 API.

For Part II please read JPA Criteria API by samples – Part-II

and in this examples in my opinion building query by programming is not so easy and maintainable  but still possible.

PS: I tested it with hibernate 3.5.1

Simple Query

		Query query = entityManager.createQuery("from SimpleBean s");
		List<SimpleBean> list = query.getResultList();

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
		Root<SimpleBean> from = criteriaQuery.from(SimpleBean.class);
		CriteriaQuery<Object> select = criteriaQuery.select(from);
		TypedQuery<Object> typedQuery = entityManager.createQuery(select);
		List<Object> resultList = typedQuery.getResultList();
		assertEqualsList(list, resultList);

Simple Query with Order

               List<SimpleBean> expected= entityManager.createQuery("from SimpleBean s order by s.pbyte asc ,s.pint desc")
                                          .getResultList();

		//...
		CriteriaQuery<Object> select = criteriaQuery.select(from);
                select.orderBy(criteriaBuilder.asc(from.get("pbyte"))
                                ,criteriaBuilder.desc(from.get("pint")));
		TypedQuery<Object> typedQuery = entityManager.createQuery(select);
               //...

Simple Query with selected fields

		Query query = entityManager.createQuery("select s.id,s.pbyte from SimpleBean s ");
		List listExpected = query.getResultList();
                //...
		CriteriaQuery<Object> select = criteriaQuery.multiselect(from.get("id"),from.get("pbyte"));

Query with single criteria

        int arg1 = 20000;
        Query query = entityManager.createQuery("from SimpleBean s where s.pint>=:arg1");
        query.setParameter("arg1", arg1);
        List<SimpleBean> list = query.getResultList();

        //...
        CriteriaQuery<Object> select = criteriaQuery.select(from);

        Predicate predicate = criteriaBuilder.ge(from.get("pint"), arg1);
        criteriaQuery.where(predicate);
        //...

Query with multiple criterias

        int arg1 = 20000;
        int arg2 = 50000;
        Query query = entityManager.createQuery("from SimpleBean s where s.pint>=:arg1 and s.pint<=:arg2");
        query.setParameter("arg1", arg1);
        query.setParameter("arg2", arg2);
        List<SimpleBean> list = query.getResultList();

        //..
        Predicate predicate1 = criteriaBuilder.ge(from.get("pint"), arg1);
        Predicate predicate2 = criteriaBuilder.le(from.get("pint"), arg2);
        criteriaQuery.where(criteriaBuilder.and(predicate1, predicate2));
        //..

Query with single literal

        String arg1 = "name";
        Query query = entityManager.createQuery("from SimpleBean s where upper(s.pstring) like upper(:arg1)");
        query.setParameter("arg1", arg1);
        List<SimpleBean> list = query.getResultList();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
        Root from = criteriaQuery.from(SimpleBean.class);
        CriteriaQuery<Object> select = criteriaQuery.select(from);

        Expression<String> literal = criteriaBuilder.upper(criteriaBuilder.literal((String) arg1));
        Predicate predicate = criteriaBuilder.like(criteriaBuilder.upper(from.get("pstring")), literal);

        criteriaQuery.where(predicate);

        TypedQuery<Object> typedQuery = entityManager.createQuery(select);
        List<Object> resultList = typedQuery.getResultList();
        assertEqualsList(list, resultList);

Query with summary (min,max,avg)

        Query query = entityManager.createQuery("select min(s.pint) from SimpleBean s");

        Object minActual = query.getSingleResult();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
        Root from = criteriaQuery.from(SimpleBean.class);

        Expression minExpression = criteriaBuilder.min(from.get("pint"));
        CriteriaQuery<Object> select = criteriaQuery.select(minExpression);

        TypedQuery<Object> typedQuery = entityManager.createQuery(select);
        Object minExpected = typedQuery.getSingleResult();
        assertEquals(minActual, minExpected);

Query with aggreation (group by)

        Query query = entityManager.createQuery("select min(s.pint),s.pbyte from SimpleBean s group by s.pbyte");

        List listExpected = query.getResultList();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
        Root from = criteriaQuery.from(SimpleBean.class);

        Expression minExpression = criteriaBuilder.min(from.get("pint"));
        Path pbytePath = from.get("pbyte");
        CriteriaQuery<Object> select = criteriaQuery.multiselect(minExpression, pbytePath);

        CriteriaQuery<Object> groupBy = select.groupBy(pbytePath);

        TypedQuery<Object> typedQuery = entityManager.createQuery(select);
        List listActual = typedQuery.getResultList();

How to get Generic Metadata from a Class at Runtime

Like Annotations, Generics are also a runtime metadata that you can process at the run time.

Here you can see how to traverse the runtime information to get this information. You Can simply traverse the inheritance tree ofr the class and get the metadata of the generic definition. Somthing like

 public static Type[] getGenericDefinitons(Class classFrom, Class class1) ;
Type[] types=getGenericDefinitons(MockClass1.class,GenericInterface.class);//[String.class,Long.class,Integer.class] expected

First The Sample Cases :


public interface GenericInterface <T,K,L>{}

 public interface MockClass1 extends GenericInterface<String,Long,Integer>{}
 public interface MockClass11<T,K,L> extends GenericInterface<T,K,L>{}
 public interface MockClass12 extends MockClass11<String,Long,Integer>{}
 public interface MockClass2 extends MockClass1{}

 public class MockClass3 implements GenericInterface<String,Long,Integer>{}
 public class MockClass4 extends MockClass3{}

 public class GenericClass <T,K,L>{}
 public class AMockClass2 extends AMockClass1{}
 public class AMockClass1 extends GenericClass<String,Long,Integer>{}

And the java class metadata traverser to retrieve the Generic Information


public class Utils {

 /**Get the Generic definition from a class for given class with given index
 * @param clz Implementing class
 * @param class1 class with generic definition
 * @param index generic index
 *  @return null if not found
 * */

 public static Type getGenericDefiniton( Class clz, Class class1, int index) {
 Type[] t = getGenericDefinitons(clz, class1);
 if (t != null && t.length > index)
 return t[index];
 return null;

 }
 /**Get the Generic definitions from a class for given class
 * @param clz Implementing class
 * @param class1 class with generic definition
 * @return null if not found
 * */
 public static Type[] getGenericDefinitons(Class clz, Class class1) {
 Type[] t = null;
 while (clz != null) {

 t = getGenericDefinitonsThis(clz, class1);
 if (t != null)
 return t;
 Class[] interfaces = clz.getInterfaces();
 for (Class class2 : interfaces) {
 t = getGenericDefinitonsThis(class2, class1);
 if (t != null)
 return t;
 }
 clz = clz.getSuperclass();
 }
 return t;
 }
 /**Get the Generic definitions from a class for given class without looking super classes
 * @param clz Implementing class
 * @param class1 class with generic definition
 * @return null if not found
 * */
 public static Type[] getGenericDefinitonsThis(Class classFrom, Class class1) {

 Type[] genericInterfaces = classFrom.getGenericInterfaces();
 for (Type type : genericInterfaces) {
 if (type instanceof ParameterizedType) {
 ParameterizedType pt = (ParameterizedType) type;

 if (class1.isAssignableFrom((Class) pt.getRawType())) {
 Type[] actualTypeArguments = pt.getActualTypeArguments();
 return actualTypeArguments;
 }
 }

 }
 // check if it if available on generic super class
 Type genericSuperclass = classFrom.getGenericSuperclass();
 if (genericSuperclass instanceof ParameterizedType) {
 ParameterizedType pt = (ParameterizedType) genericSuperclass;

 if (class1.equals(pt.getRawType())) {
 Type[] actualTypeArguments = pt.getActualTypeArguments();
 return actualTypeArguments;
 }
 }
 return null;

 }

}

And the test case

PS: This class is not tested for Multi-dimensional Generic Definitions


public class UtilsTest {
 @Test
 public void simpleInterfaceExtend(){
 Type[] genericDefinitons = Utils.getGenericDefinitons(MockClass1.class, GenericInterface.class);
 compareResults(genericDefinitons);
 }

 @Test
 public void simpleInterfaceExtend2(){

 Type[] genericDefinitons = Utils.getGenericDefinitons(MockClass2.class, GenericInterface.class);
 compareResults(genericDefinitons);
 }
 @Test
 public void simpleInterfaceExtend3(){

 Type[] genericDefinitons = Utils.getGenericDefinitons(MockClass12.class, GenericInterface.class);
 compareResults(genericDefinitons);
 }
 @Test
 public void simpleInterfaceImplements(){
 Type[] genericDefinitons = Utils.getGenericDefinitons(MockClass3.class, GenericInterface.class);
 compareResults(genericDefinitons);
 }
 @Test
 public void simpleInterfaceImplements2(){

 Type[] genericDefinitons = Utils.getGenericDefinitons(MockClass4.class, GenericInterface.class);
 compareResults(genericDefinitons);
 }

 @Test
 public void simpleClassImplements(){
 Type[] genericDefinitons = Utils.getGenericDefinitons(AMockClass1.class, GenericClass.class);
 compareResults(genericDefinitons);
 }
 @Test
 public void simpleClassImplements2(){

 Type[] genericDefinitons = Utils.getGenericDefinitons(AMockClass2.class, GenericClass.class);
 compareResults(genericDefinitons);
 }

 private void compareResults(Type[] genericDefinitons) {
 assertEquals(String.class,genericDefinitons[0]);
 assertEquals(Long.class,genericDefinitons[1]);
 assertEquals(Integer.class,genericDefinitons[2]);
 }

}

Executors.newFixedThreadPool(n) – Suspended Threads

Only Exception is Real

Image by valentin.d via Flickr

Yesterday while I am trying to organize threads in Java I noticed something strange !!

Simply the default ExecutorService  could not manage to recover suspended threads.

After a small investigation, it looks like if any of the running thread throws any RuntimeException, ExecutorService may not recover and could not start any waiting runnable.

You can check the java code below.

SmartFix: Don’t throw any exception :P

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorsTest {

	private static ExecutorService executorService;

	public static void main(String[] args) {
	    executorService = Executors.newFixedThreadPool(10);
	    for (int i = 0; i < 10000; i++) {
	        executorService.execute(new MyRunnable());
        }
    }

	public static class MyRunnable implements Runnable{

		@Override
        public void run() {
			while(true){
				long t=(long) (Math.random()*1000*10);
				try {
	                Thread.sleep(t);
                } catch (InterruptedException e) {}
                if(t<3000){
                	System.out.println(Thread.activeCount());
                	// COMMENT AND UNCOMMENT THE LINE BELOW TO SEE THE DIFFERENCE
                	throw new RuntimeException("s");

                }
			}
        }
	}
}
Enhanced by Zemanta

Focus on:Refactoring

My desk is a little untidy at the moment

Image by Neil Crosby via Flickr

Seperation of Concepts
Inversion Of Control
Desing patterns

They are all trying to tell you one common thing.

Please Make It Simple  and Organized

No matter what size is your project and how many teams/developers involved, the complexity if the code has tendency to be more complex. And after awhile it turn in to a YET another OLD piece of CRAP.

Refactoring is the only way to avoid this fate. Here is some tools and practices that would help you

Enhanced by Zemanta

Grails Productivity Tip: Depend on Your Plugin

Grails
Image via Wikipedia

Grails has amazing plugin infrastructure. In short it enables almost everything the core application can do and has really good  list of plugins: http://grails.org/Plugins

Here what I want to say is something a little bit different:

Do all your business in your application plugin

Reminder: Plugins are enabled in Grails

You can reuse all implementation in your plugins:

  • Model Object
  • Services
  • Controllers
  • Gsp pages

Plugins can define their plugin dependency, just like maven dependency.

Goal: Extreme Modularity

Model all your business in a single plugin.

You can consider grails an application container in this case which manages transactions and persistence, and ui and enable each plugin with all customization.  What you need to do is using config. groovy and ConfigurationHolder for configuration issues.

What grails will do is just starting up plugins and and the applications one by one and expose all services, domain class and controllers which will work fine.

It will increase your modularity and ease your integration issues. You can also run your plugins while your are developing them. This is the most amazing part of all the scenario. You do not need to enter pack-install cycle to test anything.

Tough Part: IDE

If you have already established something like this before with Java you would have setup your IDE for this kind of integration. But for grails there is not support as far as far as I know :( So be ready run some console commands:

cd mycore

grails package-plugin

cd ../myapp

grails install-plugin ../mycore/grails-mycore-plugin-0.1.zip

Reference Guide:

http://www.grails.org/The+Plug-in+Developers+Guide

Reblog this post [with Zemanta]