如何在Spring Data JPA规范中将枚举处理为字符串

10
尝试在数据库级别使用规范来过滤数据。 我有一个实体,其中包含另一个实体作为实例,实例变量类包含一个Emun字段。 这将默认为枚举字段的字符串形式存储在数据库中。
@Entity
public class Outer{

    @OneToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinColumn(name = "current_status")
    private Status current;

    @OneToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinColumn(name = "past_status")
    private Status past;
...
...

@Entity
public class Status{

    @Enumerated(EnumType.STRING)
    @Column(name = "state")
    private State state;

    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid",strategy = "uuid2")
    @Column(name = "id")
    private String id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "outer_id")
    private Outer outer;

我已经为这两个类创建了静态元模型。
如何使用枚举值作为字符串(而不是枚举实例)提供,创建一个用于匹配状态的谓词,并使用“where in”子句?

1
将一组“枚举”(即“状态”)传递给我,在“in”子句中完成操作,显然我需要将“字符串”转换为“枚举”。 - Rajeev Ranjan
首先,您可以嵌套实体吗?根据JPA规范,它们必须是顶层类。 - ujulu
抱歉 @ujulu,如果我的陈述有误导性。但是实体并没有嵌套,即不是内部类。请注意,两个类都是“public”。只是我没有展示完整的类。 - Rajeev Ranjan
从你的问题中并不清楚为什么你不能使用枚举值而不是字符串。如果你发布StateStrings列表,对我们来说可能会更清楚。 - ujulu
最终的谓词状态为:cb.or(root.join(Outer_.current).get(Status_.state).in(states),root.join(Outer_.past).get(Status_.state).in(states))。这对我来说解决了问题。 - Rajeev Ranjan
1个回答

3
你将实体属性建模为一个枚举类型Enum,因此 Hibernate 期望在所有的 JPQL 或 Criteria 查询中都使用枚举类型。
因此,你需要将所有的字符串映射到State枚举类型,或者使用本地 SQL 查询
Hibernate 不解析本地查询,它们基于表模型而不是实体模型。这使得你可以使用State枚举类型的字符串表示。
你可以像下面这样做:
List<State> states = ... // get or initialize your State list here
Query q = em.createNativeQuery("SELECT * FROM Status s WHERE state IN (:states)", Status.class);
q.setParameter("states", states);
List<Status> s = (List<Status>) q.getResultList();
createNativeQuery方法的第二个参数告诉Hibernate将结果集中的每条记录映射到一个Status实体。这些实体是受管理的,您可以使用它们来更新或删除映射的数据库记录。
要使用此映射,您需要确保查询选择了实体映射的所有列。我编写了一系列文章,详细介绍了不同的结果映射选项:

1
谢谢@Thorben,但是正如我在第一条评论中更新的那样,我已经得到了答案。在创建实例类的连接后,我正在通过in字段传递枚举的实例。 - Rajeev Ranjan

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