2010-11-16 36 views
1

以下JPA查詢不會編譯:Java的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的基地類:

public class PsaBase implements Serializable { 
    @Column(name = "sourceSystemId") 
    @Enumerated(EnumType.ORDINAL) 
    protected SourceSystem sourceSystem; 
    ... 
} 

查詢編譯和運行的罰款,如果我再將p.sourceSystem.id放在查詢中,並使用更加友好的方式。

非常感謝您的幫助。

回答

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 ... 
} 
+0

謝謝,幫助它編譯, 3例如,它總是綁定0.該id是我在查詢結果中查找。 – 2010-11-16 17:16:31

+0

@David:已更新。 – axtavt 2010-11-16 17:26:56

+0

啊!我明白了 - 我只是認爲0是一個默認值。非常感謝 - 這就是我所需要的。 – 2010-11-16 17:40:43