11

我有一个持久对象(Action)和自动生成的数据模型(Action_)。通过拥有一个 Action 类的对象和一个 SingularAttribute 的实例,是否可以获得与给定 SingularAttribute 对应的字段?

我需要这样的功能:

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

我的实体类(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;
    }
}

我的元模型类(Action_.java):

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

2 回答 2

11

正如 JB Nizet 建议的那样,您可以使用getJavaMember. 我发现我不需要将私有字段设置为可访问,也许 Hibernate 已经这样做了。

如果这有帮助,这里有一些对我有用的代码:

/**
 * 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);
    }
}
于 2012-02-20T11:08:02.643 回答
5

您可以使用该getJavaMember()方法获取成员,然后测试该成员是 aField还是 a Method,然后使用反射访问该字段或调用对象上的方法。

在访问/调用它之前,您可能必须使该字段或方法可访问。而且您还必须处理到对象的原始类型转换。

主要问题是:为什么需要这个?

如果您只需要这个特定的实体类,您可以简单地使用属性名称上的开关并返回适当的值:

switch (attribute.getName()) {

    case "name":
        return action.getName();
    ...
}
于 2011-08-16T12:03:43.357 回答