JPA:带有 @AtrributeConverter 和 jpa-ql 查询的 EnumSet 行,不再起作用

JPA: A row of a EnumSet with a @AtrributeConverter and jpa-ql query, that does not work anymore

提问人:Groovieman 提问时间:10/31/2023 最后编辑:Groovieman 更新时间:10/31/2023 访问量:20

问:

想象一下,您的 JavaEE 或 Spring 应用程序必须将 EnumSet 保存到数据库 JPA/Hibernate 中。最简单的方法是创建一个表/行,如下所示:

@Entity
@Setter
@Getter
public class Person {

   /* ... */     

   @ElementCollection
   @Enumerated(EnumType.STRING)
   @CollectionTable(name = "SET_ATTRIBUTE")
   private Set<EnAttribute> setOfAttributes;

   /* ... */     
}

这个简单的实现允许我们使用 JPA-QL 语言,以便通过提供枚举属性来过滤 Person 条目。这可能是我们的查找器,它驻留在 SpringJPA 存储库中(在 JavaEE 中工作类似):

public interface PersonRepo extends CrudRepository<Person, Long> {

    @Query("SELECT pers FROM Person pers WHERE :pAttr MEMBER OF pers.setOfAttributes ")
    List<Person> findPersonBy (final EnAttribute pAttr);
}

但有时,您可能会想到上面显示的过滤器的性能较低,因此您可能会通过使用简单的位字段而不是表来摆脱SET_ATTRIBUTE表和隐式 JOIN 操作。 如果 EnAttribute 的域包含的枚举项不超过 30 个,您可以尝试将枚举序号转换为数字的位置,例如整数。

幸运的是,JPA 带有一个属性转换器,可以这样使用:

@Entity
@Setter
@Getter
public class Person {

   /* ... */     

   @Convert(converter = ConverterSetOfPersAttribute.class)
   private Set<EnAttribute> setOfAttributes;

   /* ... */     
}

这非常适合通过简单地读取一个数据库行将完整的(实体)集保存和加载到数据库中/从数据库加载到应用程序中。但是有一个问题,我选择的数据类型可能是错误的。当我的应用程序启动时,我立即收到异常,JPA 试图将查找器转换为 postgres 数据库。我收到一个异常,其中包含与“bytea is not compatible with integer”类似的消息。

这个消息是有道理的,JPA/Hibernate 识别出SET_ATTRIBUTE的缺失,并将成员表达式也转换为数字表达式,并期望它是一个字节数组 (bytea)。 所以我想我选择了错误的目标数据类型(整数)。

我的问题:

  • 我应该同时使用 EnumSet 实现之一(对于 small 和 lage 枚举集)还是应该使用哪种类型将集合作为基数保存到数据库中?
  • 我知道,postgres 带有枚举的支持。postgres 休眠实现将来会支持这些功能吗?

谢谢大家!

我试图更改数据库中的集合表示,并期望 JPA-QL 查找器仍在工作,但我一定是错的。

休眠 JPA 成员 JPA-2.1 枚举

评论

0赞 Groovieman 11/12/2023
这个问题 JPA 强制枚举转换器在特定查询(where 子句)上走向了同一个方向,尤其是来自 Davide 的回复。

答: 暂无答案