Java JPA "Error compiling the query" when it uses an enum
The following JPA query doesn't compile:
@NamedQuery(name = "PSA.findBySourceSystem",
query = "SELECT p FROM PSA p WHERE p.sourceSystem.id = :sourceSystemId")
p.sourceSystem is the following enum:
public enum SourceSystem {
FIRST(3, "ABC"), SECOND(9, "DEF"), THIRD(17, "GHI");
private int id;
private String code;
...
}
and is mapped in PSA's base class:
public class PsaBase implements Serializable {
@Column(name = "sourceSystemId")
@Enumerated(EnumType.ORDINAL)
protected SourceSystem sourceSystem;
...
}
The query compiles and runs fine if I replace p.sourceS开发者_运维知识库ystem.id in the query with something more benign.
Thank you in advance for any help.
It shouldn't compile.
You have to resolve the required enum value manually before passing it as a query parameter:
@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));
EDIT:
Since sourceSystem
is annotated as @Enumerated(EnumType.ORDINAL)
, it's stored in the database as the ordinal numbers of the corresponding enum values, therefore FIRST
is stored as 0
. JPA doesn't directly support using arbitrary field of the enum value to identify it in the database. If your database schema assumes so, you can do the following trick to decouple state of your object from the database schema:
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 ...
}
精彩评论