2011-08-16 7 views
8

Tengo un objeto persistente (Acción) y un modelo de datos generado automáticamente (Acción_). Al tener un objeto de clase Action y una instancia de SingularAttribute, ¿es posible obtener el campo correspondiente al SingularAttribute dado?¿Cómo obtener el valor mapeado de SingularAttribute de un objeto persistente?

Necesito una función como esta:

public S getValue(T object,SingularAttribute<T,S> attribute); 

Mi clase de entidad (Action.java):

@Entity 
@Table(name="ACTION") 
public class Action implements Serializable { 
    private long id; 
    private String name; 

    public Action() { 
    } 


    @Id 
    @Column(unique=true, nullable=false, precision=6) 
    public long getId() { 
     return this.id; 
    } 

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


    @Column(length=50) 
    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

Mi clase meta modelo (Action_.java):

@StaticMetamodel(Action.class) 
public class Action_ { 
    public static volatile SingularAttribute<Action, Long> id; 
    public static volatile SingularAttribute<Action, String> name; 
} 
+0

APP no está ahí para proporcionar valores de los campos de un objeto, que es persistir/recuperar el objeto. Como dice la respuesta, usa la reflexión de Java. – DataNucleus

Respuesta

4

Puede usar el método getJavaMember() para obtener el miembro, luego pruebe si este miembro es un Field o un Method, y acceda al campo o llame al método sobre el objeto utilizando la reflexión.

Probablemente tendrá que hacer que el campo o método sea accesible antes de acceder/invocarlo. Y también tendrá que manejar la conversión de tipo primitivo a objetos.

La pregunta principal es: ¿por qué necesita esto?

Si lo necesita para esta clase entidad específica, simplemente se podría utilizar un interruptor en el nombre del atributo y devolver el valor adecuado:

switch (attribute.getName()) { 

    case "name": 
     return action.getName(); 
    ... 
} 
+0

Gracias por su rápida respuesta. Quiero hacer una clase general que debería poder trabajar con cualquier objeto persistente dado (usando el modelo meta). Por ejemplo, una clase para representar cualquier tabla de base de datos. El uso de la función getJavaMember() parece ser el único, pero dado que todos los objetos persistentes deben proporcionar métodos getter para sus campos, espero que la API proporcione la funcionalidad para obtener todos los campos (internamente, si es necesario, use el método getter). –

+0

Funciona. Como esperaba que SingularAttribute devuelva instancias de Método o Campo en función de dónde se establece @Column. ¡Gracias de nuevo! –

8

Como sugirió JB Nizet, puede utilizar getJavaMember. Descubrí que no era necesario que los campos privados estuvieran accesibles, tal vez Hibernate ya lo haya hecho.

En caso de que esto sea útil, aquí hay un código que funciona para mí:

/** 
* Fetches the value of the given SingularAttribute on the given 
* entity. 
* 
* @see http://stackoverflow.com/questions/7077464/how-to-get-singularattribute-mapped-value-of-a-persistent-object 
*/ 
@SuppressWarnings("unchecked") 
public static <EntityType,FieldType> FieldType getValue(EntityType entity, SingularAttribute<EntityType, FieldType> field) { 
    try { 
     Member member = field.getJavaMember(); 
     if (member instanceof Method) { 
      // this should be a getter method: 
      return (FieldType) ((Method)member).invoke(entity); 
     } else if (member instanceof Field) { 
      return (FieldType) ((Field)member).get(entity); 
     } else { 
      throw new IllegalArgumentException("Unexpected java member type. Expecting method or field, found: " + member); 
     } 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 
+0

Buena solución. Hemos derivado fácilmente una EntityAttributeCollection para que podamos iterar sobre los atributos de las entidades en una colección existente. – mazatwork

+0

¡Este es genial! ¡Puedo crear fácilmente una nueva columna en JSF sin agregar mucho código! – alexander

Cuestiones relacionadas