如何获取持久化对象的SingularAttribute映射值?

12

我有一个持久化对象(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;
}

JPA 的作用不在于提供对象字段的值,而是用于持久化/检索对象。就像回复中所说,可以使用 Java 反射。 - DataNucleus
2个回答

12

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

如果有帮助的话,这是一些对我有效的代码:

/**
 * Fetches the value of the given SingularAttribute on the given
 * entity.
 *
 * @see https://dev59.com/Rmw05IYBdhLWcg3wsz_N
 */
@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);
    }
}

不错的解决方案。我们已经轻松地派生出了一个EntityAttributeCollection,因此我们能够迭代现有集合中实体的属性。 - mazatwork
这太棒了!我可以轻松地在JSF中创建一个新列,而不需要添加太多的代码! - alexander

6
您可以使用getJavaMember()方法获取成员,然后测试该成员是一个Field还是一个Method,并使用反射访问字段或调用对象上的方法。
在访问/调用之前,您可能需要将字段或方法设置为可访问状态。您还需要处理基本类型转换为对象的情况。
主要问题是:为什么需要这个?
如果您只需要针对特定实体类使用它,您可以简单地在属性名称上使用switch语句并返回适当的值:
switch (attribute.getName()) {

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

感谢您的快速回应。我想制作一个通用类,它应该能够使用任何给定的持久化对象(使用元模型)。例如,表示数据库中任何表的类。使用getJavaMember()函数似乎是唯一的方法,但由于所有持久化对象都应提供其字段的getter方法,我希望API提供获取所有字段的功能(必要时在内部使用getter方法)。 - Sadegh Ramezanpour
它起作用了。正如我所预期的那样,SingularAttribute根据@Column设置的位置返回Method或Field实例。再次感谢! - Sadegh Ramezanpour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接