Java JPA“编译查询时出错”当它使用枚举时

发布于 2024-10-02 22:48:22 字数 663 浏览 0 评论 0原文

以下 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 的 base 类中:

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

如果我将查询中的 p.sourceSystem.id 替换为更良性的东西。

预先感谢您的帮助。

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.sourceSystem.id in the query with something more benign.

Thank you in advance for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半透明的墙 2024-10-09 22:48:23

它不应该编译。

您必须先手动解析所需的枚举值,然后再将其作为查询参数传递:

@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 ...
} 

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 ...
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文