JPA 2 向表添加引用约束使标准查询与延迟获取复杂化,需要建议

Posted

技术标签:

【中文标题】JPA 2 向表添加引用约束使标准查询与延迟获取复杂化,需要建议【英文标题】:JPA2 adding referential contraint to table complicates criteria query with lazy fetch, need advice 【发布时间】:2011-01-18 01:45:01 【问题描述】:

以下是我认为是一个非常简单的问题的大量写作。问题的根源在于我的无知,不是寻找代码而是寻找建议。

表:使用旧实体映射的 Ininvhst(Inventory-schema 库存历史)列 ihtran(库存历史转移代码):

@Basic(optional = false)
@Column(name = "IHTRAN")
private String ihtran;

ihtran 实际上是表 Intrnmst(“库存转移主数据”,其中包含“转移代码”列表)的外键。这在数据库中没有表达,因此对 Ininvhst 重新生成 JPA2 实体类产生了引用约束:

@JoinColumn(name = "IHTRAN", referencedColumnName = "TMCODE", nullable = false)
@ManyToOne(optional = false)
private Intrnmst intrnmst;

现在我以前使用 JPA2 从 Ininvhst 表中选择记录/(Ininvhst 实体),其中“ihtran”是一组值之一。我使用 in.value() 来执行此操作...这是一个 sn-p:

        cq = cb.createQuery(Ininvhst.class);
        ...
        In<String> in = cb.in(transactionType); //Get in expression for transacton types
        for (String s : transactionTypes)  //has a value
            in = in.value(s);//check if the strings we are looking for exist in the transfer master
        
        predicateList.add(in);

我的问题是 Ininvhst 曾经包含一个名为 ihtran 的字符串,但现在它包含 Ininvhst...所以我现在需要一个路径表达式:

    this.predicateList = new ArrayList<Predicate>();
    if (transactionTypes != null && transactionTypes.size() > 0)  //list of strings has some values
        Path<Intrnmst> intrnmst = root.get(Ininvhst_.intrnmst); //get transfermaster from Ininvhst
        Path<String> transactionType = intrnmst.get(Intrnmst_.tmcode); //get transaction types from transfer master
        In<String> in = cb.in(transactionType); //Get in expression for transacton types
        for (String s : transactionTypes)  //has a value
            in = in.value(s);//check if the strings we are looking for exist in the transfer master
        
        predicateList.add(in);
    

我可以将 ihtran 连同一个同时引用“IHTRAN”的连接列一起添加回实体中吗?或者我应该使用投影以某种方式返回 Ininvhst 以及现在是 Intrnmst 实体的一部分的 ihtran 字符串。或者我应该使用投影来返回 Ininvhst 并以某种方式将 Intrnmst 限制为 ihtran 字符串。

更多信息:我在 Web 应用程序中使用所选 Ininvhst 对象的结果列表,包含 Ininvhst 对象列表的类被转换为 json 对象。可能有相当多的序列化方法可以导航对象图,问题是我当前的获取策略是惰性的,因此它会命中连接实体 (Intrnmst intrnmst),并且此时没有可用的实体管理器。此时我已阻止对象序列化连接列,但现在我丢失了一个关键数据。

我想我说的太多了,但我知道的不够多,我不知道你们 JPA 专家需要什么。我想要的是我的原始对象既具有字符串对象又能够加入同一列(ihtran),但如果这不可能或不可取,我想听听我应该做什么以及为什么。

伪代码/英文就更好了。

【问题讨论】:

【参考方案1】:

我可以将 ihtran 添加回实体吗 以及一个既是 引用“IHTRAN”?

是的。只需将其中一个设为只读 (insertable/updateable=false)

如果您使用的是 EclipseLink,您还可以为外键添加 QueryKey。

如果您在序列化之前访问该关系,那么它将可用。否则,将其设为 EAGER,或在您的查询中加入 fetch 它。

【讨论】:

以上是关于JPA 2 向表添加引用约束使标准查询与延迟获取复杂化,需要建议的主要内容,如果未能解决你的问题,请参考以下文章

使用 JPA 标准的“不在”约束

JPA 2.1 Eager Fetch 属性

在redshift中,如何在创建表后向表中添加多个约束?

添加唯一约束但忽略现有表数据

标准 JPA 2 与 3 个表格

远程案例中的延迟/急切加载策略(JPA)