I have a persistent object (Action) and auto generated data model (Action_). By having an object of Action class and an instance of SingularAttribute, is it possible to get the field corresponding to the given SingularAttribute?
I need a function like this:
public S getValue(T object,SingularAttribute<T,S> attribute);
My entity class (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;
}
}
My meta model class (Action_.java):
@StaticMetamodel(Action.class)
public class Action_ {
public static volatile SingularAttribute<Action, Long> id;
public static volatile SingularAttribute<Action, String> name;
}
As JB Nizet suggested, you can use getJavaMember
. I found that I didn't need to set private fields to be accessible, perhaps Hibernate has already done this.
In case this is helpful, here's some code which works for 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);
}
}
You could use the getJavaMember()
method to get the member, then test if this member is a Field
or a Method
, and access the field or call the method on the object using reflection.
You will probably have to make the field or method accessible before accessing/invoking it. And you will also have to handle primitive type conversion to objects.
The main question is: why do you need this?
If you need it only for this specific entity class, you could simply use a switch on the attribute name and return the appropriate value:
switch (attribute.getName()) {
case "name":
return action.getName();
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With