Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get SingularAttribute mapped value of a persistent object?

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;
}
like image 262
Sadegh Ramezanpour Avatar asked Aug 16 '11 11:08

Sadegh Ramezanpour


2 Answers

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);
    }
}
like image 54
Rich Avatar answered Nov 16 '22 00:11

Rich


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();
    ...
}
like image 23
JB Nizet Avatar answered Nov 15 '22 23:11

JB Nizet