JPA的AttributeConverter是否适用于查询子句?

4

我有一个像这样的JPA实体:

@Entity
public class RectangleEntity
{

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;

   @Column
   private Integer x;

   @Column
   private Integer y;

   @Column
   @Convert(converter = ColorConverter.class)
   private Color color;

}

我的ColorConverter如下所示:
@Converter
public class ColorConverter implements AttributeConverter<Color, String[]> {

 @Override
 public String[] convertToDatabaseColumn(Color color) {
  switch(color) {
      case REDISH : return {"red","pink"};
      case GREENISH: return {"green","cyan"};
  }
  return sb.toString();
 }

 @Override
 public Color convertToEntityAttribute(String... colorStrings) {

  if(colorStrings == null || colorStrings.length != 1) {
     return null;
  }
  if(colorStrings[0].equals("red") || colorStrings[0].equals("pink")) {
     return REDISH; 
  } else if(colorStrings[0].equals("green") || colorStrings[0].equals("cyan")) {
     return GREENISH; 
  }
 }

}

问题是我想在查询中使用我的列值,就像这样:

Expression<String> colorPath = root.get("color");
Predicate predicate = requestStatePath.in(Color.REDISH);
Predicate[] predicatesArr = predicates.toArray(new Predicate[predicates.size()]);
criteriaQuery.where(predicatesArr);
CriteriaQuery<RectangleEntity> criteriaQuery = criteriaBuilder.createQuery(RectangleEntity.class);
TypedQuery<RectangleEntity> query = this.em.createQuery(criteriaQuery);
query.getResultList();

我希望这个查询可以选择我所有颜色字段为粉色或红色的记录,因为它们是reddish

这种查询是否可行?

1个回答

1
我认为您的转换器没有按照您想要的方式执行。首先,需要意识到这不符合JPA中有效的AttributeConverter定义。JPA仅针对基本类型定义了AttributeConverters的支持,并且不将String[]视为基本类型。而Hibernate虽然允许String[]存在,但它只会将其视为可序列化对象。
您是否希望将这些String[]存储到数据库数组中?如果是的话,Hibernate目前不支持数据库数组类型(尽管我们一直在讨论在6.0版本中添加对其的支持)。
但是,回答您的确切问题...是的,JPA表示AttributeConverter应该在查询中自动应用,在第3.8节中概述了某些准则:

...持久性提供程序必须在Java Persistence查询语言查询或标准查询中使用的路径表达式中对属性值的实例应用任何转换方法(例如在比较、批量更新等操作中) ,然后将它们发送到数据库进行查询执行。当这些转换后的属性与字面值或参数一起在比较操作中使用时,还必须转换与其进行比较的字面值或参数的值。...

但是你最终会得到一个像<BINARY> in <BINARY>这样的谓词。


1
谢谢您的回复。 关于String[],您是正确的。那是我的错误。 我的问题不在于存储值,而是由于我使用了Oracle视图。 我想用一个类型的参数查询我的视图,该参数将转换为一组值,这些值将用作“in”值。 我没有理解您的最后一句话。 - A.v

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