我想从按优先级列排序的表中获取数据。我们使用javaee 6,GF 3.1。
我们的实体看起来像这样
@Entity
@Table(name="ITEMS")
@NamedQueries({
@NamedQuery(
name = "Item.findbyPriority",
query = "select i from Item i where ORDER BY i.priority DESC" )
})
public class Item implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Integer id;
String data inputFile;
@Enumerated(EnumType.ORDINAL)
Priority priority;
...
}优先级被定义
public enum Priority {
HIGH,
NORMAL;
}然而,Item.findbyPriority查询按序号排序,并返回错误的顺序。如果我将优先级类更改为
public enum Priority {
NORMAL,
HIGH;
}它可以正常工作。但这并不是真正有力的措施。如果我添加新的优先级使用或重新排序它呢?
我试图重写compareTo方法,但它在Enum类中是最终的。
在这种情况下我能做什么?怎么才能做得好呢?
我知道我可以将优先级存储为number等,但我不得不手动将实体同步到Enum,这并不是非常好。也许“PrePersist”、“PreUpldate”和“PostLoad方法”是要走的路?那么jpql查询会是什么样的呢?
谢谢,
米兰
发布于 2012-05-19 17:15:20
影响命名查询之外优先级顺序的唯一方法是选择枚举属性的类型(序号,字符串)。
即使重写compareTo是大声的,它也不会改变事物,因为在执行查询时不会调用它。原因是JPQL查询被转换为SQL查询,并且没有从SQL查询调用Java方法的概念。
另外,指定回调方法也没有帮助,因为它们与生成查询或影响结果列表的顺序无关。
您可以做的是有一个后处理方法来定义您的列表的顺序,然后在执行命名查询的结果之后调用它。
发布于 2021-07-13 17:27:24
在JPA 2.1之后,您可以使用@Convert注释。这允许在保存数据库之前将枚举的对象转换为舒适的排序视图。
public enum Priority {
NORMAL(100),
HIGH(200);
private final int sortNum;
Priority(int sortNum) {
this.sortNum = sortNum;
}
public int getSortNum() {
return this.sortNum;
}
}@Converter(autoApply = true)
public class PriorityConverter implements AttributeConverter<Priority, Integer> {
@Override
public Integer convertToDatabaseColumn(Priority attribute) {
return attribute == null ? null : attribute.getSortNum();
}
@Override
public Priority convertToEntityAttribute(Integer dbData) {
return dbData == null
? null
: Stream.of(Priority.values())
.filter(t -> t.getSortNum() == dbData)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
String.format("Priority with sortNum %s is not exist", dbData)));
}
}您的枚举对象将以100或200的形式保存在数据库中。将来您可以轻松地添加新的优先级对象。
https://stackoverflow.com/questions/9215369
复制相似问题