我有一个枚举作为实体的属性.当我尝试在JPQL suqry中使用枚举时,会给出错误.除了传递它作为参数,使用什么正确的方法?
枚举是
package com.divudi.data; public enum Sex { Male,Female,UnkNown,Other,}
实体是
package com.divudi.entity.lab; import com.divudi.data.Sex; import com.divudi.entity.Item; import com.divudi.entity.WebUser; import java.io.Serializable; import java.util.Date; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.Temporal; @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public class InvestigationItemValueFlag extends InvestigationItemValue implements Serializable { private static final long serialVersionUID = 1L; @Enumerated(EnumType.STRING) Sex sex; @ManyToOne InvestigationItem investigationItemOfLabelType; @ManyToOne private InvestigationItem investigationItemOfValueType; @ManyToOne InvestigationItem investigationItemOfFlagType; @ManyToOne Item item; long fromAge; long toAge; @Lob private String flagMessage; @Lob String highMessage; @Lob String lowMessage; @Lob String normalMessage; boolean displayFlagMessage; boolean displayHighMessage; boolean displayLowMessage; boolean displaynormalMessage; public InvestigationItem getInvestigationItemOfLabelType() { return investigationItemOfLabelType; } public void setInvestigationItemOfLabelType(InvestigationItem investigationItemOfLabelType) { this.investigationItemOfLabelType = investigationItemOfLabelType; } public String getHighMessage() { return highMessage; } public void setHighMessage(String highMessage) { this.highMessage = highMessage; } public String getLowMessage() { return lowMessage; } public void setLowMessage(String lowMessage) { this.lowMessage = lowMessage; } public String getnormalMessage() { return normalMessage; } public void setnormalMessage(String normalMessage) { this.normalMessage = normalMessage; } public boolean isdisplayFlagMessage() { return displayFlagMessage; } public void setdisplayFlagMessage(boolean displayFlagMessage) { this.displayFlagMessage = displayFlagMessage; } public boolean isdisplayHighMessage() { return displayHighMessage; } public void setdisplayHighMessage(boolean displayHighMessage) { this.displayHighMessage = displayHighMessage; } public boolean isdisplayLowMessage() { return displayLowMessage; } public void setdisplayLowMessage(boolean displayLowMessage) { this.displayLowMessage = displayLowMessage; } public boolean isdisplaynormalMessage() { return displaynormalMessage; } public void setdisplaynormalMessage(boolean displaynormalMessage) { this.displaynormalMessage = displaynormalMessage; } public Item getItem() { return item; } public void setItem(Item item) { this.item = item; } public InvestigationItemValueFlag() { } public Sex getSex() { return sex; } public void setSex(Sex sex) { this.sex = sex; } public long getFromAge() { return fromAge; } public void setFromAge(long fromAge) { this.fromAge = fromAge; } public long getToAge() { return toAge; } public void setToAge(long toAge) { this.toAge = toAge; } public String getFlagMessage() { return flagMessage; } public void setFlagMessage(String flagMessage) { this.flagMessage = flagMessage; } public InvestigationItem getInvestigationItemOfValueType() { return investigationItemOfValueType; } public void setInvestigationItemOfValueType(InvestigationItem investigationItemOfValueType) { this.investigationItemOfValueType = investigationItemOfValueType; } public InvestigationItem getInvestigationItemOfFlagType() { return investigationItemOfFlagType; } public void setInvestigationItemOfFlagType(InvestigationItem investigationItemOfFlagType) { this.investigationItemOfFlagType = investigationItemOfFlagType; } }
JSF托管bean如下(仅相关代码)
public String getPatientDynamicLabel(InvestigationItem ii,Patient p) { String dl; String sql; dl = ii.getName(); long ageInDays = commonFunctions.calculateAgeInDays(p.getPerson().getdob(),Calendar.getInstance().getTime()); sql = "select f from InvestigationItemValueFlag f where f.fromAge < " + ageInDays + " and f.toAge > " + ageInDays + " and f.investigationItemOfLabelType.id = " + ii.getId(); List<InvestigationItemValueFlag> fs = getIivfFacade().findBysql(sql); for (InvestigationItemValueFlag f : fs) { if (f.getSex() == p.getPerson().getSex()) { dl = f.getFlagMessage(); } } return dl; }
错误是
java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: Exception Description: Error compiling the query [select f from InvestigationItemValueFlag f where f.sex = com.divudi.data.Male and f.fromAge < 12419 and f.toAge > 12419 and f.investigationItemOfLabelType.id = 2678],line 1,column 57: unkNown identification variable [com]. The FROM clause of the query does not declare an identification variable [com].
解决方法
您不应该使用字符串连接来将参数传递给查询.您应该使用参数(命名,最喜欢的):
String jpql = "select f from InvestigationItemValueFlag f" + " where f.sex = :sex" + " and ..."; Query query = em.createquery(jpql); query.setParameter("sex",Sex.Male);
这将会照顾正确的转义,正确的sql生成(枚举可以映射为字符串或序号),并避免JPQL注入攻击.
也请不要命名sql或findBysql,而是实际上是JPQL.