以下JPA查询无法编译:
@NamedQuery(name = "PSA.findBySourceSystem",
query = "SELECT p FROM PSA p WHERE p.sourceSystem.id = :sourceSystemId")
p.sourceSystem是以下枚举:
public enum SourceSystem {
FIRST(3, "ABC"), SECOND(9, "DEF"), THIRD(17, "GHI");
private int id;
private String code;
...
}
并映射到PSA的 base 类:
public class PsaBase implements Serializable {
@Column(name = "sourceSystemId")
@Enumerated(EnumType.ORDINAL)
protected SourceSystem sourceSystem;
...
}
如果我用更好的方式替换查询中的p.sourceSystem.id,查询将编译并运行正常。
提前感谢您的帮助。
答案 0 :(得分:2)
它不应该编译。
在将其作为查询参数传递之前,您必须手动解析所需的枚举值:
@NamedQuery(name = "PSA.findBySourceSystem",
query = "SELECT p FROM PSA p WHERE p.sourceSystem = :sourceSystem")
public enum SourceSystem {
...
private static Map<Integer, SourceSystem> valuesById = new HashMap<Integer, SourceSystem>();
static {
for (SourceSystem s: values())
valuesById.put(s.id, s);
}
public static SourceSystem findById(int id) {
return valuesById.get(id);
}
}
em.createNamedQuery("PSA.findBySourceSystem")
.setParameter("sourceSystem", SourceSystem.findById(sourceSystemId));
修改强>
由于sourceSystem
注释为@Enumerated(EnumType.ORDINAL)
,因此它作为相应枚举值的序号存储在数据库中,因此FIRST
存储为0
。 JPA不直接支持使用枚举值的任意字段在数据库中标识它。如果您的数据库模式假定,您可以执行以下技巧来将对象的状态与数据库模式分离:
public class PsaBase implements Serializable {
protected SourceSystem sourceSystem;
@Column(name = "sourceSystemId")
public Integer getSourceSystemId() {
return sourceSystem.getId();
}
public void setSourceSystemId(Integer id) {
this.sourceSystem = SourceSystem.findById(id);
}
... getter and setter of sourceSystem with @Transient ...
}