2011-08-16 7 views
8

Ho un oggetto persistente (azione) e un modello di dati generato automaticamente (azione_). Avendo un oggetto di classe Action e un'istanza di SingularAttribute, è possibile ottenere il campo corrispondente al SingularAttribute dato?Come ottenere il valore mappato SingularAttribute di un oggetto persistente?

Ho bisogno una funzione come questa:

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

La mia classe di entità (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; 
    } 
} 

mia classe del modello meta (Action_.java):

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

APP non è lì per fornire i valori dei campi di un oggetto, è persistere/recuperare l'oggetto. Come dice la risposta, usa Java reflection. – DataNucleus

risposta

4

È possibile utilizzare il metodo getJavaMember() per ottenere il membro, quindi verificare se questo membro è un o Method, e accedere al campo o chiamare il metodo sull'oggetto usando la riflessione.

Probabilmente dovrete rendere il campo o il metodo accessibile prima di accedervi/invocarlo. E dovrai anche gestire la conversione del tipo primitivo in oggetti.

La domanda principale è: perché ne hai bisogno?

Se ne avete bisogno solo per questa specifica classe di entità, si può semplicemente utilizzare un interruttore sul nome dell'attributo e restituire il valore appropriato:

switch (attribute.getName()) { 

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

Grazie per la tua rapida risposta. Voglio fare una classe generale che dovrebbe essere in grado di lavorare con qualsiasi oggetto persistente (usando il meta modello). Ad esempio una classe per rappresentare qualsiasi tabella di database. L'uso della funzione getJavaMember() sembra essere l'unico modo, ma poiché tutti gli oggetti persistenti dovrebbero fornire metodi getter per i loro campi, mi aspetto che l'API fornisca la funzionalità per ottenere tutti i campi (usando internamente il metodo getter se necessario). –

+0

Funziona. Come mi aspettavo SingularAttribute restituire istanze di Metodo o Campo in base a dove è impostato @Column. Grazie ancora! –

8

Come suggerito JB Nizet, è possibile utilizzare getJavaMember. Ho scoperto che non avevo bisogno di impostare i campi privati ​​per essere accessibile, forse Hibernate lo ha già fatto.

Nel caso in cui questo sia utile, ecco qualche codice che funziona per me:

/** 
* 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

Bella soluzione. Abbiamo facilmente derivato un EntityAttributeCollection in modo da poter iterare su attributi di entità in una raccolta esistente. – mazatwork

+0

Questo è fantastico! Posso creare facilmente una nuova colonna in JSF senza aggiungere molto codice! – alexander