How to use JPA to enumerate the where clause in jpql?
•
Java
I have an enumeration as an attribute of an entity When I try to use enumeration in jpql suqry, I give an error In addition to passing it as a parameter, what is the correct method to use?
Enumeration is
package com.divudi.data; public enum Sex { Male,Female,UnkNown,Other,}
Entity is
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 managed beans are as follows (relevant code only)
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; }
The mistake is
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].
Solution
You should not use string concatenation to pass parameters to a query You should use parameters (named, favorite):
String jpql = "select f from InvestigationItemValueFlag f" + " where f.sex = :sex" + " and ..."; Query query = em.createQuery(jpql); query.setParameter("sex",Sex.Male);
This will take care of correct escape, correct SQL generation (enumeration can be mapped to string or sequence number), and avoid jpql injection attack
Please also do not name sql or findsysql, but actually jpql
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码