Utilizando funções aninhadas no Hibernate

Quem utiliza Criteria já deve ter precisado utilizar funções aninhadas ( como sum(abs(propriedade)) ). Infelizmente a class Projections não dispoem deste recurso, e a classe que implementa as agregações ( AggregateProjection ) não foi projetada pensando nisso.

Baseado na class AggregateProjection implementei uma solução com um construtor que recebe um array de string com as funções a serem aninhadas na ordem do array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package br.com.dclick.hibernate.criterion;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.SimpleProjection;
import org.hibernate.type.Type;

public class AggregateFunctionsProjection extends SimpleProjection {

    protected final String propertyName;
    private final String aggregate[];

    public AggregateFunctionsProjection(String[] aggregate, String propertyName) {
        this.aggregate = aggregate;
        this.propertyName = propertyName;
    }

    public String toString() {
        return this.mountSql(this.propertyName).toString();
    }

    public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
        return new Type[] { criteriaQuery.getType(criteria, propertyName) };
    }

    public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException {
        return this.mountSql( criteriaQuery.getColumn(criteria, propertyName) )
        .append(" as y")
        .append(loc)
        .append('_')
        .toString();
    }

    private StringBuffer mountSql(String property) {

        StringBuffer start = new StringBuffer();
        StringBuffer end = new StringBuffer();

        for (int i = 0; i < this.aggregate.length; i++) {
            start.append( this.aggregate[i] + "(" );
            end.append( ")" );
        }

        return start.append(property).append(end);

    }

}

Pronto. Agora e so adicionar ao seu criterio:

1
2
3
4
5
6
String[] funcoes = {"sum", "abs"};

HibernateSessionFactory.getSession()
.createCriteria(Produto.class)
.setProjection( new AggregateFunctionsProjection(funcoes, "nomeDaPropriedadeDaSuaClasse") )
.list();

2 comentários

  1. Henrique em 4.dez.07 às 11:49 am

    Muito bom!. Já estou utilizando…

  2. Nadilson em 15.jan.09 às 8:37 am

    Cara, que dicas boas de hibernate existem no teu site.
    Parabens!

Deixe Seu Comentário