2013-07-20 12 views
11

Ho un enum come attributo di un'entità. Quando provo a usare l'enum in un suqry JPQL, dà un errore. Qual è il metodo corretto da usare tranne il fatto di passarlo come parametro?Come utilizzare JPA Enum in una clausola JPQL dove?

Enum è

package com.divudi.data; 

public enum Sex { 
    Male, 
    Female, 
    Unknown, 
    Other, 
} 

Ente

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 gestito è la seguente (codice rilevante solo)

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; 
} 

errore viene

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]. 

risposta

16

Non si deve utilizzare la concatenazione di stringhe per passare parametri a una query. Si consiglia di utilizzare parametri (denominati, preferibilmente):

String jpql = 
    "select f from InvestigationItemValueFlag f" 
    + " where f.sex = :sex" 
    + " and ..."; 
Query query = em.createQuery(jpql); 
query.setParameter("sex", Sex.Male); 

che si prenderà cura di una corretta fuga, la generazione SQL corretta (enum potrebbe essere mappato come stringa o come un numero ordinale), ed evitare gli attacchi di iniezione JPQL.

Inoltre si prega di non nominare qualcosa sql o findBySQL whan in realtà è JPQL.