2011-08-16 10 views
8

Mam trwały obiekt (działanie) i automatycznie generowany model danych (Action_). Posiadając obiekt klasy Action i instancję SingularAttribute, czy możliwe jest uzyskanie pola odpowiadającego danemu SingularAttribute?Jak uzyskać zmapowaną wartość SingularAttribute dla trwałego obiektu?

muszę funkcję tak:

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

moja klasa podmiot (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; 
    } 
} 

Moja meta klasie modelu (Action_.java):

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

JPA nie jest tam, aby zapewnić wartości pól obiektu, to utrzymują się/odebrania obiektu. Jak mówi odpowiedź, użyj refleksji Java. – DataNucleus

Odpowiedz

4

Możesz użyć metody getJavaMember(), aby uzyskać element, a następnie sprawdź, czy ten element to Field lub Method i uzyskaj dostęp do pola lub wywołaj metodę na obiekcie za pomocą odbicia.

Najprawdopodobniej będziesz musiał udostępnić pole lub metodę przed uzyskaniem dostępu/wywołaniem go. Będziesz także musiał obsługiwać pierwotną konwersję typów do obiektów.

Główne pytanie brzmi: dlaczego tego potrzebujesz?

Jeśli jest to potrzebne tylko dla tej konkretnej klasy podmiotu, można po prostu użyć przełącznika na nazwę atrybutu i zwróci odpowiednią wartość:

switch (attribute.getName()) { 

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

Dziękujemy za szybką odpowiedź. Chcę utworzyć ogólną klasę, która powinna być w stanie pracować z dowolnym trwałym obiektem (przy użyciu meta modelu). Na przykład klasa reprezentująca dowolną tabelę bazy danych. Używanie funkcji getJavaMember() wydaje się być jedyną metodą, ale ponieważ wszystkie trwałe obiekty powinny zapewniać metody getter dla ich pól, oczekuję, że interfejs API zapewni funkcjonalność do uzyskania wszystkich pól (wewnętrznie używając metody getter, jeśli to konieczne). –

+0

To działa. Tak jak się spodziewałem, SingularAttribute zwraca instancje metody lub pola w zależności od miejsca ustawienia kolumny @ kolumna. Dzięki jeszcze raz! –

8

Jak sugeruje JB Nizet, można użyć getJavaMember. Zauważyłem, że nie muszę ustawiać prywatnych pól, aby były dostępne, być może Hibernate już to zrobił.

W przypadku, jest to pomocne, oto niektóre kod, który działa dla mnie:

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

Ładne rozwiązanie. Łatwo wyprowadziliśmy EntityAttributeCollection, dzięki czemu jesteśmy w stanie powtórzyć atrybuty encji w istniejącej kolekcji. – mazatwork

+0

Ten jest świetny! Mogę z łatwością utworzyć nową kolumnę w JSF bez dodawania dużej ilości kodu! – alexander

Powiązane problemy