2012-05-14 13 views
17

Hace poco cambié mi esquema para que mis clases hereden de una súper clase, el problema es que mi método de comparación que genera un registro de auditoría, usando el reflejo de Java, ahora solo está recorriendo los campos del niño clase, no la superclase, ¿hay alguna manera de obtener todos los CAMPOS? ¿o necesito echarlo en la súper clase ...?¿Cómo lograr que Java se refleje para detectar campos en la súper clase? no solo la clase real

Heres mi método a continuación:

public static <T> String GenerateChangeLogForEntity(T old, T updated) { 
     String text = ""; 
     try { 
      Field[] fields = old.getClass().getDeclaredFields(); 
      if(fields != null) { 
       BaseController.getLogger().info("Z1 num fields:"+fields.length); 
       for (Field field : fields) { 
        if(field.isAnnotationPresent(Column.class)) { 
         String fieldName = field.getName(); 
         BaseController.getLogger().info(field.getName()); 
         if(field.isAnnotationPresent(Variation.class)) { 
          Variation v = field.getAnnotation(Variation.class); 
          fieldName = v.friendlyName(); 
         } 
         field.setAccessible(true); 
         if(field.get(old) != null && field.get(updated) != null) { 
          if(!(field.get(old)).equals(field.get(updated))) { 
           text += "<p><span class=\"field-name\">"+fieldName+"</span> changed from: <strong>"+GetFriendlyFieldValueForChangeLog(field.get(old))+"</strong> to: <strong>"+GetFriendlyFieldValueForChangeLog(field.get(updated)) + "</strong></p>"; 
          } 
         } 
         if(field.get(old) == null && field.get(updated) != null) { 
          text += "<p><span class=\"field-name\">"+fieldName+"</span> changed from: <strong>empty</strong> to: <strong>"+GetFriendlyFieldValueForChangeLog(field.get(updated)) + "</strong></p>"; 
         } 
         if(field.get(old) != null && field.get(updated) == null) { 
          text += "<p><span class=\"field-name\">"+fieldName+"</span> changed from: <strong>"+GetFriendlyFieldValueForChangeLog(field.get(updated))+"</strong> to <strong>empty</strong>" + "</p>"; 
         } 
         field.setAccessible(false); 
        } 
       } 
      } 
     } catch(IllegalAccessException e) {} 
     return text; 
    } 
+0

NB: Probablemente no deba configurar 'field.setAccessible (false)' para evitar condiciones de carrera en entornos de subprocesos múltiples ... –

+1

su medio es: 'instance.getClass(). GetSuperCLass(). GetDeclaredFields() ¿? – MJM

+0

Gracias MJM, gracias a todos, yip que lo hizo fácil como un pastel! :) – Baconbeastnz

Respuesta

29

Puede utilizar este método hasta que this.getClass().getSuperClass()getSuperClass() devuelve null para obtener los campos de padres.

Entonces, lo mejor sería que factorices tu código. Implemente un método que tome una lista de Field como parámetro y haga su parte lógica dentro de él, y un método principal que busque campos a través de un bucle while(superClass != null).

+2

reloj para el método getFilds(), en mi caso no funciona para la superclase. Solo tuve éxito con getDeclaredFilds() –

6

Aunque es tarde, estoy agregando mi sugerencia ya que es una buena solución.

El marco de resorte proporciona una buena clase Util org.springframework.util.ReflectionUtils esta clase tiene varios métodos que podemos usar. Para obtener una instancia de campo de un atributo de objectClass y superClasses que utilicé ReflectionUtils.findField(clazz, fieldName);

Lo bueno con la utilidad es que no arroja una excepción. En su lugar, devuelve nulo para los no válidos, por lo que puede manejarlo con gracia.

Cuestiones relacionadas