Mostrando postagens com marcador Hibernate. Mostrar todas as postagens
Mostrando postagens com marcador Hibernate. Mostrar todas as postagens

segunda-feira, 10 de junho de 2013

Detached Object no Hibernate ou desvincular objeto da sessão

Fala pessoal(como se fosse muita gente),

Gostaria de compartilhar um código com a comunidade, que consiste em retirar totalmente um objeto do hibernate, ou seja desvincular o objeto da sessao e falar "Olha cara, agora é um objeto normal sem proxy sem bags sem NADAA!".

Encontrei alguns problemas quando utilizei RMI ou EJB3 ou xml, sendo que quando uma entidade traz uma lista de objetos e ele é do tipo lazy ou mesmo a lista em si vem como "Bag", no momento que o sistema tenta de-serializar ou transformar o objeto em xml, ele vai como bag e não como list ou collection, 0o ... WTF ??

Pois é, e quando do outro lado vc tem um hibernate3.jar ainda passa, mas e quando não tem ?

Ou quando vc não quer que o objeto não acesse os dados do tipo Lazy ??

Ou quando as versoes do hibernate são diferentes e ele não consegue de-serializar o objeto, da aquele errão e vem na cabeça : E AGORA JOSÉ?

Pois é[2], e a primeira solução que vem na cabeça é : vou copiar as informações para um objeto novo e passar esse objeto, pois ele perderá as referencias com o proxy do hibernate -_- funciona ... mas da um trabalho cabuloso!

Por isso, em algumas discussões em foruns chegamos a essa solução :

 import org.apache.commons.logging.Log;  
 import org.apache.commons.logging.LogFactory;  
 import org.hibernate.Hibernate;  
 import org.hibernate.proxy.HibernateProxy;  
 import javax.xml.bind.annotation.XmlAccessType;  
 import javax.xml.bind.annotation.XmlAccessorType;  
 import javax.xml.bind.annotation.XmlTransient;  
 import java.beans.BeanInfo;  
 import java.beans.Introspector;  
 import java.beans.PropertyDescriptor;  
 import java.lang.reflect.Constructor;  
 import java.lang.reflect.Field;  
 import java.lang.reflect.Method;  
 import java.util.ArrayList;  
 import java.util.Collection;  
 import java.util.Collections;  
 import java.util.HashMap;  
 import java.util.HashSet;  
 import java.util.List;  
 import java.util.Map;  
 import java.util.Set;  
 public class HibernateDetachUtility {  
   private static final Log LOG = LogFactory.getLog(HibernateDetachUtility.class);  
   public static enum SerializationType {  
     SERIALIZATION, JAXB  
   }  
   public static void nullOutUninitializedFields(Object value, SerializationType serializationType) throws Exception {  
     long start = System.currentTimeMillis();  
     Set<Integer> checkedObjs = new HashSet<Integer>();  
     nullOutUninitializedFields(value, checkedObjs, 0, serializationType);  
     long duration = System.currentTimeMillis() - start;  
     if (duration > 1000) {  
       LOG.info("Detached [" + checkedObjs.size() + "] objects in [" + duration + "]ms");  
     } else {  
       LOG.debug("Detached [" + checkedObjs.size() + "] objects in [" + duration + "]ms");  
     }  
   }  
   private static void nullOutUninitializedFields(Object value, Set<Integer> nulledObjects, int depth,  
     SerializationType serializationType) throws Exception {  
     if (depth > 50) {  
       LOG.warn("Getting different object hierarchies back from calls: " + value.getClass().getName());  
       return;  
     }  
     if ((value == null) || nulledObjects.contains(System.identityHashCode(value))) {  
       return;  
     }  
     nulledObjects.add(System.identityHashCode(value));  
     if (value instanceof Object[]) {  
       Object[] objArray = (Object[]) value;  
       for(int i = 0; i < objArray.length; i++)  
       {  
         nullOutUninitializedFields(objArray[i], nulledObjects, depth +1, serializationType);  
       }  
     } else if (value instanceof Collection) {  
       // Null out any entries in initialized collections  
       for (Object val : (Collection) value) {  
         nullOutUninitializedFields(val, nulledObjects, depth + 1, serializationType);  
       }  
     } else if (value instanceof Map) {  
       for (Object key : ((Map)value).keySet()) {  
         nullOutUninitializedFields(((Map)value).get(key), nulledObjects, depth+1, serializationType);  
         nullOutUninitializedFields(key, nulledObjects, depth+1, serializationType);  
       }  
     }   
     if (serializationType == SerializationType.JAXB) {  
       XmlAccessorType at = value.getClass().getAnnotation(XmlAccessorType.class);  
       if (at != null && at.value() == XmlAccessType.FIELD) {  
         //System.out.println("----------XML--------- field access");  
         nullOutFieldsByFieldAccess(value, nulledObjects, depth, serializationType);  
       } else {  
         //System.out.println("----------XML--------- accessor access");  
         nullOutFieldsByAccessors(value, nulledObjects, depth, serializationType);  
       }  
     } else if (serializationType == SerializationType.SERIALIZATION) {  
       //        System.out.println("-----------JRMP-------- field access");  
       nullOutFieldsByFieldAccess(value, nulledObjects, depth, serializationType);  
     }  
   }  
   private static void nullOutFieldsByFieldAccess(Object object, Set<Integer> nulledObjects, int depth,  
     SerializationType serializationType) throws Exception {  
     Class tmpClass = object.getClass();  
     List<Field> fieldsToClean = new ArrayList<Field>();  
     while (tmpClass != null && tmpClass != Object.class) {  
       Collections.addAll(fieldsToClean, tmpClass.getDeclaredFields());  
       tmpClass = tmpClass.getSuperclass();  
     }  
     nullOutFieldsByFieldAccess(object, fieldsToClean, nulledObjects, depth, serializationType);  
   }  
   @SuppressWarnings("unchecked")  
   private static void nullOutFieldsByFieldAccess(Object object, List<Field> classFields, Set<Integer> nulledObjects, int depth,  
                           SerializationType serializationType) throws Exception {  
     boolean accessModifierFlag = false;  
     for (Field field : classFields) {  
       accessModifierFlag = false;  
       if (!field.isAccessible()) {  
         field.setAccessible(true);  
         accessModifierFlag = true;  
       }  
       Object fieldValue = field.get(object);  
       if (fieldValue instanceof HibernateProxy) {  
         Object replacement = null;  
         if (fieldValue.getClass().getName().contains("javassist")) {  
           Class assistClass = fieldValue.getClass();  
           try {  
             Method m = assistClass.getMethod("writeReplace");  
             replacement = m.invoke(fieldValue);  
             String className = fieldValue.getClass().getName();  
             className = className.substring(0, className.indexOf("_$$_"));  
             if (!replacement.getClass().getName().contains("hibernate")) {  
               nullOutUninitializedFields(replacement, nulledObjects, depth+1, serializationType);  
               field.set(object, replacement);  
             } else {  
               replacement = null;  
             }  
           } catch (Exception e) {  
             System.out.println("Unable to write replace object " + fieldValue.getClass());  
           }  
         }  
         if (replacement == null) {  
              field.set(object, replacement);  
           /*String className = ((HibernateProxy) fieldValue).getHibernateLazyInitializer().getEntityName();  
           Class clazz = Class.forName(className);  
           Class[] constArgs = {Integer.class};  
           Constructor construct = null;  
           try {  
             construct = clazz.getConstructor(constArgs);  
             replacement = construct.newInstance((Integer) ((HibernateProxy) fieldValue).getHibernateLazyInitializer().getIdentifier());  
             field.set(object, replacement);  
           } catch (NoSuchMethodException nsme) {  
             try {  
               Field idField = clazz.getDeclaredField("id");  
               Constructor ct = clazz.getDeclaredConstructor();  
               ct.setAccessible(true);  
               replacement = ct.newInstance();  
               if (!idField.isAccessible()) {  
                 idField.setAccessible(true);  
               }  
               idField.set(replacement, (Integer) ((HibernateProxy) fieldValue).getHibernateLazyInitializer().getIdentifier());  
             } catch (Exception e) {  
               e.printStackTrace();  
               System.out.println("No id constructor and unable to set field id for base bean " + className);  
             }  
             field.set(object, replacement);  
           }*/  
         }  
       } else {  
         if (fieldValue instanceof org.hibernate.collection.PersistentCollection) {  
           // Replace hibernate specific collection types  
           if (!((org.hibernate.collection.PersistentCollection) fieldValue).wasInitialized()) {  
             field.set(object, null);  
           } else {  
             Object replacement = null;  
             if (fieldValue instanceof Map) {  
               replacement = new HashMap((Map) fieldValue);  
             } else if (fieldValue instanceof List) {  
               replacement = new ArrayList((List) fieldValue);  
             } else if (fieldValue instanceof Set) {  
               replacement = new HashSet((Set) fieldValue);  
             } else if (fieldValue instanceof Collection) {  
               replacement = new ArrayList((Collection)fieldValue);  
             }  
             setField(object, field.getName(), replacement);  
             nullOutUninitializedFields(replacement, nulledObjects, depth+1, serializationType);  
           }  
         } else {  
           if (fieldValue != null &&  
               (fieldValue.getClass().getName().contains("org.rhq") ||  
                 fieldValue instanceof Collection ||  
                 fieldValue instanceof Object[] ||   
                 fieldValue instanceof Map))  
             nullOutUninitializedFields((fieldValue), nulledObjects, depth+1, serializationType);  
         }  
       }  
       if (accessModifierFlag) {  
         field.setAccessible(false);  
       }  
     }  
   }  
   private static void nullOutFieldsByAccessors(Object value, Set<Integer> nulledObjects, int depth,  
     SerializationType serializationType) throws Exception {  
     // Null out any collections that aren't loaded  
     BeanInfo bi = Introspector.getBeanInfo(value.getClass(), Object.class);  
     PropertyDescriptor[] pds = bi.getPropertyDescriptors();  
     for (PropertyDescriptor pd : pds) {  
       Object propertyValue = null;  
       try {  
         propertyValue = pd.getReadMethod().invoke(value);  
       } catch (Throwable lie) {  
         if (LOG.isDebugEnabled()) {  
           LOG.debug("Couldn't load: " + pd.getName() + " off of " + value.getClass().getSimpleName(), lie);  
         }  
       }  
       if (!Hibernate.isInitialized(propertyValue)) {  
         try {  
           if (LOG.isDebugEnabled()) {  
             LOG.debug("Nulling out: " + pd.getName() + " off of " + value.getClass().getSimpleName());  
           }  
           Method writeMethod = pd.getWriteMethod();  
           if ((writeMethod != null) && (writeMethod.getAnnotation(XmlTransient.class) == null)) {  
             pd.getWriteMethod().invoke(value, new Object[] { null });  
           } else {  
             nullOutField(value, pd.getName());  
           }  
         } catch (Exception lie) {  
           LOG.debug("Couldn't null out: " + pd.getName() + " off of " + value.getClass().getSimpleName()  
             + " trying field access", lie);  
           nullOutField(value, pd.getName());  
         }  
       } else {  
         if ((propertyValue instanceof Collection)  
           || ((propertyValue != null) && propertyValue.getClass().getName().startsWith("org.rhq.core.domain"))) {  
           nullOutUninitializedFields(propertyValue, nulledObjects, depth + 1, serializationType);  
         }  
       }  
     }  
   }  
   private static void setField(Object object, String fieldName, Object newValue) {  
     try {  
       Field f = object.getClass().getDeclaredField(fieldName);  
       if (f != null) {  
         // try to set the field this way  
         f.setAccessible(true);  
         f.set(object, newValue);  
       }  
     } catch (NoSuchFieldException e) {  
       // ignore this  
     } catch (IllegalAccessException e) {  
       // ignore this  
     }  
   }  
   private static void nullOutField(Object value, String fieldName) {  
     try {  
       Field f = value.getClass().getDeclaredField(fieldName);  
       if (f != null) {  
         // try to set the field this way  
         f.setAccessible(true);  
         f.set(value, null);  
       }  
     } catch (NoSuchFieldException e) {  
       // ignore this  
     } catch (IllegalAccessException e) {  
       // ignore this  
     }  
   }  
 }  

Detalhe que eu comentei a parte do ID, pois nao é todo mundo que usa o nome "ID" como chave, portanto caso necessário implementem !

Ele funciona sem a parte do id, pois objetos lazy seriam "buscados" nesse momento, caso não haja a necessidade, deixem comentado pois ele setará NULL nos objetos.

\m/(0.0)\m/

Espero que tenha ajudado pessoal !

Abraços !

quarta-feira, 29 de setembro de 2010

ResultTransformer Inteligente =)

Pessoal .. estou passando aki p vcs um result transformer inteligente ! ....


 /**  
  *   
  * Result transformer inteligente  
  *   
  * @author Sergio , Alterado por Caio Rodrigo Paulucci  
  *   
  * @see AliasToBeanResultTransformer  
  *   
  *   
  *   
  *   
  *   
  *   Similar ao AliasToBeanResultTransformer poróm ele aceita o uso de  
  *   "nestedProperties" (aquela que vocó usa na JSTL ou EL)  
  *   
  *   no criteria e pode instanciar mais de um tipo de classe.  
  *   
  *   Inclusive uma parte do código foi copiado da classe original.  
  *   
  * <br />  
  *   
  *   <b>1ó Forma de utilização</b>  
  *   
  *   caso mais comum criar uma lista de objetos do mesmo tipo  
  *   (HistoricoRegistroVO)  
  *   
  * <br />  
  *   
  *   <code>  
 Criteria crit= createCriteria(HistoricoRegistroVO.class);  
 criteria.add(Restrictions.eq("this.registroVO.id", idDemanda));  
 ProjectionList projectionList = Projections.projectionList();  
 //seleciono somente os campos que me interessam, na estrutura real dos objetos (sem a necessidade de criação dos DTOs)  
 projectionList.add(Projections.property("this.ativo"), "ativo");  
 projectionList.add(Projections.property("this.descricao"), "descricao");  
 projectionList.add(Projections.property("this.encaminhamentoInterno"), "encaminhamentoInterno");  
 criteria.createAlias("this.usuarioVO", "usr");  
 criteria.createAlias("usr.unidadeVO", "unr");  
 projectionList.add(Projections.property("usr.login"), "usuarioVO.login");  
 projectionList.add(Projections.property("usr.nome"), "usuarioVO.nome");  
 projectionList.add(Projections.property("usr.id"), "usuarioVO.id");  
 projectionList.add(Projections.property("unr.descricao"), "usuarioVO.unidadeVO.descricao");  
 projectionList.add(Projections.property("this.dataUltimoMovimento"), "dataUltimoMovimento");  
 criteria.setProjection(projectionList);  
 //transformo o resultado no objeto passado e somente as propriedades e objetos que selecionei estóo preenchidas  
 criteria.setResultTransformer(new InteligentResultTransformer(HistoricoRegistroVO.class));  
 List resultado = criteria);  
 </code>  
  *   
  *   
  *   
  *   
  *   
  *   <b>2ó Forma de utilização</b>  
  *   
  *   Criar uma lista de objetos com um tipo definido pelo usuório  
  *   (programmer)  
  *   
  *   <code>  
 //Considerando que temos uma classe RegistroDenunciaReclamacaoVO que ó filho do RegistroVO  
 //preciso instónciar a classe correta de acordo com uma determinada condição  
 Criteria crit= createCriteria(RegistroVO.class);  
 criteria.createAlias("this.tipoRegistroVO", "tir");  
 criteria.createAlias("this.instituicaoFinanceiraVO", "ifr", Criteria.LEFT_JOIN);  
 ProjectionList projectionList = Projections.projectionList();  
 //seleciono os campos que me interessam  
 projectionList.add(Projections.property("this.enderecoVO"), "enderecoVO");  
 projectionList.add(Projections.property("ifr.nomeFantasia"), "instituicaoFinanceiraVO.nomeFantasia");  
 projectionList.add(Projections.property("tir.descricao"), "tipoRegistroVO.descricao");  
 projectionList.add(Projections.property("tir.id"), "tipoRegistroVO.id");  
 projectionList.add(Projections.property("tir.comportamentoTipoRegistroVO"), "tipoRegistroVO.comportamentoTipoRegistroVO");  
 projectionList.add(Projections.property("this.id"), "id");  
 projectionList.add(Projections.property("this.idCrm"), "idCrm");  
 projectionList.add(Projections.property("this.idConsulta"), "idConsulta");  
 //esses dois campos pertencem a classe RegistroDenunciaReclamacaoVO somente  
 projectionList.add(Projections.property("this.dataRanking"), "dataRanking");  
 projectionList.add(Projections.property("this.rankingCarimbo"), "rankingCarimbo");  
 criteria.setProjection(projectionList);  
 //ao invós de passar a classe como no exemplo anterior  
 //eu passo uma classe que implementa a interface ResultClass  
 InteligentResultTransformer rt = new InteligentResultTransformer(new ResultClass(){  
 //aqui eu recebo um Map onde tenho como chave os alias adicionados no projectionList  
 //e como valores os resultados retornados pela consulta  
 public Class getResultClass(Map resultMap) {  
 //faóo uma comparação e retorno o tipo da classe que quero criar a instóncia para essa linha  
 ComportamentoTipoRegistroVO comportamento = (ComportamentoTipoRegistroVO) resultMap.get("tipoRegistroVO.comportamentoTipoRegistroVO");  
 if(DadosConstantes.COMPORTAMENTO_INFORMACAO.equals(comportamento.getId())){  
 return RegistroVO.class;  
 }  
 if(DadosConstantes.COMPORTAMENTO_IRREGULARIDADE.equals(comportamento.getId())){  
 return RegistroDenunciaReclamacaoVO.class;  
 }  
 return null;  
 }  
 });  
 criteria.setResultTransformer(rt);  
 criteria);  
 </code>  
  *   
  *   
  *   
  *   
  *   
  *   
  */  
 public class InteligentResultTransformer implements ResultTransformer {  
      private static final long serialVersionUID = -7124932916590109519L;  
      /**  
       *   
       * Classe de resultado (se o tipo da classe for fixo)  
       */  
      private Class resultClass;  
      /**  
       *   
       * objeto para acessar as propriedades de um tipo de classe  
       */  
      private PropertyAccessor propertyAccessor;  
      /**  
       *   
       * Implemntaóao que deveró fornecer java.lang.Class a ser instónciado para a  
       * linha atual do registro  
       */  
      private ResultClass rc;  
      /**  
       *   
       * Cache de propertyAccessor, para evitar de ficar instónciando esse fiduma  
       * toda hora.  
       *   
       * Se nóo fosse pesado instanciar ele o hibernate nóo usaria uma varióvel de  
       * instóncia  
       *   
       * para guardar ele  
       */  
      private HashMap propertyAccessors = new HashMap();  
      /**  
       *   
       * Tupla de registros retornados pela consulta  
       */  
      private Object[] tuple;  
      /**  
       *   
       * Alias adicionados no Projections.projectionList()  
       */  
      private String[] aliases;  
      /**  
       *   
       * Tipo dinamico para a coleção a ser criada  
       *   
       * @param rc  
       */  
      public InteligentResultTransformer(ResultClass rc) {  
           this.rc = rc;  
      }  
      /**  
       *   
       * A coleção a ser criada seró de um tipo somente  
       *   
       *   
       *   
       * @param resultClass  
       */  
      public InteligentResultTransformer(Class resultClass) {  
           if (resultClass == null)  
                throw new IllegalArgumentException("resultClass cannot be null");  
           this.resultClass = resultClass;  
      }  
      /*  
       *   
       * (non-Javadoc)  
       *   
       * @see  
       * org.hibernate.transform.ResultTransformer#transformTuple(java.lang.Object  
       * [], java.lang.String[])  
       */  
      public Object transformTuple(Object[] tuple, String[] aliases) {  
           this.tuple = tuple;  
           this.aliases = aliases;  
           Object result;  
           try {  
                // instancia a classe de resultado  
                result = getResultClass().newInstance();  
                for (int i = 0; i < aliases.length; i++) {  
                     String alias = aliases[i];  
                     if (alias != null) {  
                          if (tuple[i] == null) {  
                               continue;  
                          }  
                          /*  
                           * se o alias contóm ponto ó porque a propriedade a ser  
                           * setada deveró ser  
                           *   
                           * navegada ató o final para ser preenchida  
                           *   
                           * (Ex: registroVO.tipoRegistroVO.descricao  
                           *   
                           * - instancia uma vez o tipoRegistroVO  
                           *   
                           * - seta a descricao com o valor da tupla)  
                           */  
                          if (alias.indexOf(".") != -1) {  
                               String[] split = alias.split("\\.");  
                               Object resultado = result;  
                               for (int j = 0; j < split.length; j++) {  
                                    String property = split[j];  
                                    // se for a óltima propriedade o valor da tupla  
                                    // deveró ser setado nela  
                                    if (j == (split.length - 1)) {  
                                         PropertyUtils.setProperty(resultado, property,  
                                                   tuple[i]);  
                                         break;  
                                    }  
                                    // do contrório instancio o tipo da propriedade se  
                                    // necessório e passo para o próximo  
                                    Object valor = PropertyUtils.getProperty(resultado,  
                                              property);  
                                    if (valor == null) {  
                                         Class tipo = PropertyUtils.getPropertyType(  
                                                   resultado, property);  
                                         valor = tipo.newInstance();  
                                         PropertyUtils.setProperty(resultado, property,  
                                                   valor);  
                                    }  
                                    resultado = valor;  
                               }  
                          } else {  
                               // se estiver em modo inteligente  
                               if (this.isInInteligentMode()) {  
                                    // pode ser que a propriedade nóo exista na classe  
                                    // que foi retornada pelo ResultClass  
                                    if (PropertyUtils.isWriteable(result, alias)) {  
                                         Setter mainSetter = getPropertyAcessor()  
                                                   .getSetter(getResultClass(), alias);  
                                         mainSetter.set(result, tuple[i], null);  
                                    }  
                               } else {  
                                    // do contrório nóo ó admissóvel que a propriedade  
                                    // nóo exista na classe informada  
                                    Setter mainSetter = getPropertyAcessor().getSetter(  
                                              getResultClass(), alias);  
                                    mainSetter.set(result, tuple[i], null);  
                               }  
                          }  
                     }  
                }  
           } catch (Exception e) {  
                throw new HibernateException(e);  
           }  
           return result;  
      }  
      /**  
       *   
       * Retornar a classe que deveró ser instanciada e preenchida com o resultado  
       *   
       * @return  
       */  
      private Class getResultClass() {  
           // se o rc ó nulo nóo estó em modo inteligente  
           if (!this.isInInteligentMode()) {  
                return this.resultClass;  
           }  
           // recupero um mapa com o resultado cró retornado pelo hibernate  
           Map propriedades = getMap(tuple, aliases);  
           // invoco o result class que foi passado com as propridades  
           Class resultClass2 = rc.getResultClass(propriedades);  
           // e ele deveró me passar o tipo da classe a ser instanciada  
           return resultClass2;  
      }  
      /**  
       *   
       * Cria um mapa de propriedades para passar para a instóncia da ResultClass  
       *   
       * @param tuple  
       *   
       * @param aliases  
       *   
       * @return  
       */  
      private Map getMap(Object[] tuple, String[] aliases) {  
           HashMap map = new HashMap();  
           for (int i = 0; i < aliases.length; i++) {  
                map.put(aliases[i], tuple[i]);  
           }  
           return map;  
      }  
      /*  
       *   
       * (non-Javadoc)  
       *   
       * @see  
       * org.hibernate.transform.ResultTransformer#transformList(java.util.List)  
       */  
      public List transformList(List collection) {  
           return collection;  
      }  
      /**  
       *   
       * Retorna o property acessor de acordo com a classe que seró instónciada  
       *   
       * @return  
       */  
      public PropertyAccessor getPropertyAcessor() {  
           if (propertyAccessor == null && !this.isInInteligentMode()) {  
                propertyAccessor = new ChainedPropertyAccessor(  
                          new PropertyAccessor[] {  
                                    PropertyAccessorFactory.getPropertyAccessor(  
                                              resultClass, null),  
                                    PropertyAccessorFactory  
                                              .getPropertyAccessor("field") });  
           }  
           if (this.isInInteligentMode()) {  
                Class resultClass2 = this.getResultClass();  
                String className = resultClass2.getName();  
                Object propertyAcessor = this.propertyAccessors.get(className);  
                if (propertyAcessor == null) {  
                     this.propertyAccessors.put(  
                               className,  
                               new ChainedPropertyAccessor(new PropertyAccessor[] {  
                                         PropertyAccessorFactory.getPropertyAccessor(  
                                                   resultClass2, null),  
                                         PropertyAccessorFactory  
                                                   .getPropertyAccessor("field") }));  
                }  
                return (PropertyAccessor) this.propertyAccessors.get(className);  
           }  
           return this.propertyAccessor;  
      }  
      /**  
       *   
       *   
       *   
       * @param resultClass  
       */  
      public void setResultClass(ResultClass resultClass) {  
           this.rc = resultClass;  
      }  
      /**  
       *   
       * Quando o {@link InteligentResultTransformer} ó instanciado para criar um  
       * tipo de objeto  
       *   
       * Esse mótodo retorna false.  
       *   
       * Quando essa classe ó instanciada com uma instancia do ResultClass  
       *   
       * Ele retorna true.  
       *   
       * @return  
       */  
      private boolean isInInteligentMode() {  
           return this.rc != null;  
      }  
 }  

e o ResultClass :

 import java.util.Map;  
 /**  
  *   
  * Classe de resultado, deveró retornar o tipo do objeto para ser instanciado  
  * de acordo com o resultMap passado como parómetro  
  *   
  * @see InteligentResultTransformer  
  * @author deinf.sdantas  
  *   
  */  
 public interface ResultClass {  
      public Class getResultClass(Map resultMap);  
 }  

domingo, 7 de fevereiro de 2010

Criando consultas trazendo objeto populado apenas com campos necessarios

Bom ... me perguntaram como fazer o hibernate trazer um objeto populado apenas com os objetos necessarios ... por exemplo trazer um Usuario apenas com as propriedades nome e id populados ... facil , segue o passo a passo :

----------------------------------------------------------------------------------

1 -Criar um construtor (Alem do construtor padrao) com as propriedades nome e id por exemplo :

public Usuario(Integer id , String nome){
   this.setId(id) ;
   this.setNome(nome);
}

2 - Fazer o hql com o construtor ... como ?? facil !

Query qUsuario = super.createQuery("Select new Usuario(obj.id,obj.nome) from Usuario obj");

3 - Pegar os dados na list :

return qUsuario.list();

----------------------------------------------------------------------------------

Com isso ele vai trazer o objeto Usuario apenas com o id e o nome populado ... assim ele nao traz o resto .. a exibicao e a consulta ficam muito mais rapidos .. sem os joins !! :D

quinta-feira, 5 de novembro de 2009

Java - Para quem usa TOPLINK ( JPA )

Bom .. estou postando uma framework de codigo fonte aberto q eu criei aqui p vcs ! ... segue o link :

http://jpautil.googlecode.com

Chama-se : JPAUtil ... é uma biblioteca que auxilia a criação de HQL de forma dinâmica, passando um exemplo de objeto populado ( Como o Example do Hibernate ), porém essa biblioteca leva em consideração os sub objetos.
Ajuda o desenvolvedor a instanciar objetos de forma dinâmica.

Tem aki alguns exemplos do que ela faz :


public class Main {
public static void main(String[] args){

JPAUtil jpaUtil = new JPAUtil();
Util util = new Util();

Grupo grupoVazio = new Grupo(); //Funcao para instanciar todos os metodos util.instanciaOsSubCamposVazios(grupoVazio);
grupoVazio.setNome("testeGrupo"); grupoVazio.getUsuario().setNome("caio"); grupoVazio.getUsuario().getEndereco().setNomeDaRua("teste"); grupoVazio.getUsuario().getEndereco().setNumero(10); grupoVazio.getUsuario().getMenu().setDescricao("Menu teste"); grupoVazio.getUsuario().getMenu().setCodigoPermissao("01010041"); grupoVazio.getUsuario().getMenu().setNumeroTeste(50);

util.setaNullNosCamposObjetoVazios(grupoVazio);
System.out.println(jpaUtil.getHQLByExample(grupoVazio));
}
} Resultado :
SELECT objPrincipal FROM Grupo objPrincipal WHERE (objPrincipal.nome = 'testeGrupo' ) AND (objPrincipal.usuario.nome = 'caio' AND objPrincipal.usuario.endereco.nomeDaRua = 'teste' AND objPrincipal.usuario.endereco.numero = 10 AND objPrincipal.usuario.menu.descricao = 'Menu teste' AND objPrincipal.usuario.menu.codigoPermissao = '01010041' AND objPrincipal.usuario.menu.numeroTeste = 50)