【问题标题】:Issue Using Hibernate Criteria object with composite key使用带有复合键的 Hibernate Criteria 对象的问题
【发布时间】:2009-10-19 19:48:23
【问题描述】:

注意:由于提供了 cmets,我已更改提供的详细信息。新的技术细节实际上是我目前正在尝试运行的代码。

我的 OneToMany / ManyToOne 双向关系之一目前出现了一个奇怪的问题。

在父表中,我有一个 long 作为标识符,而子表除了另一个字段之外也有该列,它构成了它的复合键。

在我查询的示例数据中,子表中有 1 条父记录和 3 条相关记录。目前,当我使用条件对象查询表时,我得到了 3 个父 (CoPolicyPointer) 记录,其中 2 个没有关联的子 (CoTransactionSummary) 表链接,然后是正确填充的第三个。我本来希望只能得到一个结果,这就是我感到困惑的原因。您知道为什么会发生这种情况吗?

我在下面提供了更多技术数据。

父表 (CoPolicyPointer) 列数据类型 SystemAssignId 字符串(主键) PolicyPrefixCd 字符串 PolicyId 字符串 PolicySeqNo int 子表(CoTransaction 摘要) 列数据类型 SystemAssignId 字符串(复合键) TransSeqId int(复合键) TransType varchar(4)

Criteria 语句如下所示:

Criteria criteria = session.createCriteria(classToUse);
criteria.createAlias("coTransactionSummaries", "ts");
criteria.add(Restrictions.ne("ts.transInProcessCd", "VIEW"));
criteria.add(Restrictions.gt("ts.transSeqId", Short.valueOf("0")));
criteria.add(Restrictions.eq(BaseCoPolicyPointer.COL_POLICY_PREFIX_CD,
            policyNumber.getPrefix().getLiteral()));
criteria.add(Restrictions.eq(BaseCoPolicyPointer.COL_POLICY_ID,
            policyNumber.getId()));

父类看起来像:

@Entity(name = "CoPolicyPointer")
public class CoPolicyPointerRedo {
private static final String CLASS_NAME = CoPolicyPointerRedo.class
        .getName();
private static final Logger logger = Logger.getLogger(CLASS_NAME);

private String systemAssignId;
private String policyPrefixCd;
private String policyId;
private String policyNumber;
private Short policySeqNo;
private Set coTransactionSummaries;

@Id
public String getSystemAssignId() {
    return systemAssignId;
}

public void setSystemAssignId(String systemAssignId) {
    this.systemAssignId = systemAssignId;
}

@Column
public String getPolicyId() {
    return policyId;
}

public void setPolicyId(String policyId) {
    this.policyId = policyId;
}

@Column
public String getPolicyPrefixCd() {
    return policyPrefixCd;
}

public void setPolicyPrefixCd(String policyPrefixCd) {
    this.policyPrefixCd = policyPrefixCd;
}

@Column
public Short getPolicySeqNo() {
    return policySeqNo;
}

public void setPolicySeqNo(Short policySeqNo) {
    this.policySeqNo = policySeqNo;
}


@OneToMany(targetEntity = CoTransactionSummaryRedo.class, mappedBy = "coPolicyPointer")
public Set getCoTransactionSummaries() {
    return coTransactionSummaries;
}

public void setCoTransactionSummaries(Set coTransactionSummaries) {
    this.coTransactionSummaries = coTransactionSummaries;
}

}

子类看起来像:

@Entity(name = "CoTransactionSummary")
public class CoTransactionSummaryRedo {
private static final String CLASS_NAME = CoTransactionSummaryRedo.class
        .getName();
private static final Logger logger = Logger.getLogger(CLASS_NAME);

private String transTypeCd;
private String transInProcessCd;
private CoPolicyPointerRedo coPolicyPointer;

private CoTransactionSummaryIdRedo id;

@EmbeddedId
public CoTransactionSummaryIdRedo getId() {
    return id;
}

public void setId(CoTransactionSummaryIdRedo id) {
    this.id = id;
}

@Column
public String getTransInProcessCd() {
    return transInProcessCd;
}

public void setTransInProcessCd(String transInProcessCd) {
    this.transInProcessCd = transInProcessCd;
}

@Column
public String getTransTypeCd() {
    return transTypeCd;
}

public void setTransTypeCd(String transTypeCd) {
    this.transTypeCd = transTypeCd;
}

@ManyToOne()
@JoinColumn(name = "systemAssignId", insertable = false, updatable = false)
public CoPolicyPointerRedo getCoPolicyPointer() {
    return coPolicyPointer;
}

public void setCoPolicyPointer(CoPolicyPointerRedo coPolicyPointer) {
    this.coPolicyPointer = coPolicyPointer;
}


}

子类的ID类如下:

@Embeddable
public class CoTransactionSummaryIdRedo implements java.io.Serializable {

private String systemAssignId;
private short transSeqId;

public CoTransactionSummaryIdRedo() {
}

public CoTransactionSummaryIdRedo(String systemAssignId, short transSeqId) {
    this.systemAssignId = systemAssignId;
    this.transSeqId = transSeqId;
}

@Column
public String getSystemAssignId() {
    return systemAssignId;
}

public void setSystemAssignId(String systemAssignId) {
    this.systemAssignId = systemAssignId;
}

@Column
public short getTransSeqId() {
    return transSeqId;
}

public void setTransSeqId(short transSeqId) {
    this.transSeqId = transSeqId;
}

@Override
public boolean equals(Object other) {
    if ((this == other))
        return true;
    if ((other == null))
        return false;
    if (!(other instanceof CoTransactionSummaryIdRedo))
        return false;
    CoTransactionSummaryIdRedo castOther = (CoTransactionSummaryIdRedo) other;

    return ((this.getSystemAssignId() == castOther.getSystemAssignId()) || (this
            .getSystemAssignId() != null
            && castOther.getSystemAssignId() != null && this
            .getSystemAssignId().equals(castOther.getSystemAssignId())))
            && (this.getTransSeqId() == castOther.getTransSeqId());
}

@Override
public int hashCode() {
    int result = 17;

    result = 37
            * result
            + (getSystemAssignId() == null ? 0 : this.getSystemAssignId()
                    .hashCode());
    result = 37 * result + this.getTransSeqId();
    return result;
}

}

我已经打开了 TRACE 的日志记录,这是正在生成的内容。

08:20:47,907 调试 SQL:111 - 选择 this_.systemAssignId 作为 systemAs1_1_2_, this_.policyId 作为 policyId1_2_, this_.policyPrefixCd 作为 policyPr3_1_2_, this_.policySeqNo 作为 policySe4_1_2_, ts1_.systemAssignId 作为 systemAs1_0_0_, ts1_.transSeqId 作为 transSeqId0_如transInP3_0_0_,ts1_.transTypeCd如transTyp4_0_0_,copolicypo4_.systemAssignId如systemAs1_1_1_,copolicypo4_.policyId如policyId1_1_,copolicypo4_.policyPrefixCd如policyPr3_1_1_,copolicypo4_.policySeqNo如policySe4_1_1_从CoPolicyPointer THIS_内部联接上this_.systemAssignId = ts1_.systemAssignId CoTransactionSummary ts1_左外连接CoPolicyPointer copolicypo4_ on ts1_.systemAssignId=copolicypo4_.systemAssignId where this_.policyPrefixCd=?和 this_.policyId=?而 this_.policySeqNo=? 休眠:选择this_.systemAssignId为systemAs1_1_2_,this_.policyId为policyId1_2_,this_.policyPrefixCd为policyPr3_1_2_,this_.policySeqNo为policySe4_1_2_,ts1_.systemAssignId为systemAs1_0_0_,ts1_.transSeqId为transSeqId0_0_,ts1_.transInProcessCd为transInP3_0_0_,ts1_.transTypeCd为transTyp4_0_0_ ,copolicypo4_.systemAssignId如systemAs1_1_1_,copolicypo4_.policyId如policyId1_1_,copolicypo4_.policyPrefixCd如policyPr3_1_1_,copolicypo4_.policySeqNo如policySe4_1_1_从CoPolicyPointer THIS_内部联接上this_.systemAssignId = ts1_.systemAssignId CoTransactionSummary ts1_左外连接CoPolicyPointer copolicypo4_上ts1_.systemAssignId = copolicypo4_ .systemAssignId where this_.policyPrefixCd=?和 this_.policyId=?而 this_.policySeqNo=? 19:14:30,938 调试 AbstractBatcher:513 - 准备语句 19:14:30,969 调试字符串类型:151 - 将“WA”绑定到参数:1 19:14:30,969 调试字符串类型:151 - 将“0100036449”绑定到参数:2 19:14:30,969 DEBUG ShortType:151 - 将“0”绑定到参数:3 19:14:30,969 DEBUG AbstractBatcher:426 - 即将打开 ResultSet(打开 ResultSets:0,全局:0) 19:14:30,969 DEBUG Loader:717 - 处理结果集 19:14:30,969 调试加载器:722 - 结果集行:0 19:14:30,969 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_0_0_ 19:14:30,969 DEBUG ShortType:193 - 返回“0”作为列:transSeqId0_0_ 19:14:30,969 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_1_1_ 19:14:30,969 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_1_2_ 19:14:30,969 调试加载器:1197 - 结果行:EntityKey[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=0, systemAssignId=00502000000000}],EntityKey[CoPolicyPointerRedo#00502000000000],EntityKey[CoPolicyPointer20000005000000000050000000005 19:14:30,969 调试加载程序:1379 - 从 ResultSet 初始化对象:[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=0, systemAssignId=00502000000000}] 19:14:30,969 调试 AbstractEntityPersister:2059 - 水合实体:[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=0, systemAssignId=00502000000000}] 19:14:30,969 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_0_0_ 19:14:30,969 DEBUG StringType:193 - 返回“PCNM”作为列:transInP3_0_0_ 19:14:30,969 DEBUG StringType:193 - 返回“PCNM”作为列:transTyp4_0_0_ 19:14:30,969 调试加载程序:1379 - 从 ResultSet 初始化对象:[CoPolicyPointerRedo#00502000000000] 19:14:30,969 调试 AbstractEntityPersister:2059 - 水合实体:[CoPolicyPointerRedo#00502000000000] 19:14:30,985 DEBUG StringType:193 - 返回 '0100036449' 作为列:policyId1_1_ 19:14:30,985 DEBUG StringType:193 - 返回 'WA' 作为列:policyPr3_1_1_ 19:14:30,985 DEBUG ShortType:193 - 返回 '0' 作为列:policySe4_1_1_ 19:14:30,985 调试加载器:722 - 结果集行:1 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_0_0_ 19:14:30,985 DEBUG ShortType:193 - 返回“1”作为列:transSeqId0_0_ 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_1_1_ 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_1_2_ 19:14:30,985 DEBUG Loader:1197 - 结果行:EntityKey[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=1, systemAssignId=00502000000000}], EntityKey[CoPolicyPointerRedo#00502000000000], EntityKey[CoPolicyPointer20000005000000000050000000005 19:14:30,985 调试加载程序:1379 - 从 ResultSet 初始化对象:[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=1, systemAssignId=00502000000000}] 19:14:30,985 调试 AbstractEntityPersister:2059 - 水合实体:[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=1, systemAssignId=00502000000000}] 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_0_0_ 19:14:30,985 DEBUG StringType:193 - 返回“PCNM”作为列:transInP3_0_0_ 19:14:30,985 DEBUG StringType:193 - 返回“PCNM”作为列:transTyp4_0_0_ 19:14:30,985 调试加载器:722 - 结果集行:2 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_0_0_ 19:14:30,985 DEBUG ShortType:193 - 返回“5”作为列:transSeqId0_0_ 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_1_1_ 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_1_2_ 19:14:30,985 DEBUG Loader:1197 - 结果行:EntityKey[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=5, systemAssignId=00502000000000}], EntityKey[CoPolicyPointerRedo#00502000000000], EntityKey[CoPolicyPointer20000005000000000050000000005 19:14:30,985 调试加载程序:1379 - 从 ResultSet 初始化对象:[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=5, systemAssignId=00502000000000}] 19:14:30,985 调试 AbstractEntityPersister:2059 - 水合实体:[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=5, systemAssignId=00502000000000}] 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_0_0_ 19:14:30,985 DEBUG StringType:193 - 返回“PCNM”作为列:transInP3_0_0_ 19:14:30,985 DEBUG StringType:193 - 返回“PCNM”作为列:transTyp4_0_0_ 19:14:30,985 调试加载器:722 - 结果集行:3 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_0_0_ 19:14:30,985 DEBUG ShortType:193 - 返回“6”作为列:transSeqId0_0_ 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_1_1_ 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_1_2_ 19:14:30,985 DEBUG Loader:1197 - 结果行:EntityKey[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=6, systemAssignId=00502000000000}],EntityKey[CoPolicyPointerRedo#00502000000000],EntityKey[CoPolicyPointer20000005000000000050000000005 19:14:30,985 调试加载程序:1379 - 从 ResultSet 初始化对象:[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=6, systemAssignId=00502000000000}] 19:14:30,985 调试 AbstractEntityPersister:2059 - 水合实体:[CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=6, systemAssignId=00502000000000}] 19:14:30,985 DEBUG StringType:193 - 返回 '00502000000000' 作为列:systemAs1_0_0_ 19:14:30,985 DEBUG StringType:193 - 返回“PCNM”作为列:transInP3_0_0_ 19:14:30,985 DEBUG StringType:193 - 返回“PCNM”作为列:transTyp4_0_0_ 19:14:30,985 DEBUG Loader:744 - 完成处理结果集(4 行) 19:14:30,985 DEBUG AbstractBatcher:433 - 即将关闭 ResultSet(打开 ResultSets:1,全局:1) 19:14:30,985 DEBUG AbstractBatcher:418 - 即将关闭 PreparedStatement(打开 PreparedStatements:1,全局:1) 19:14:30,985 调试 AbstractBatcher:562 - 结束声明 19:14:30,985 DEBUG ConnectionManager:427 - 积极释放 JDBC 连接 19:14:30,985 DEBUG ConnectionManager:464 - 释放 JDBC 连接 [(打开 PreparedStatements:0,全局:0)(打开 ResultSets:0,全局:0)] 19:14:30,985 DEBUG DriverManagerConnectionProvider:152 - 返回连接到池,池大小:1 19:14:30,985 调试加载器:874 - 水合对象总数:5 19:14:30,985 调试 TwoPhaseLoad:130 - 解析 [CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=0, systemAssignId=00502000000000}] 的关联 19:14:30,985 调试 DefaultLoadEventListener:199 - 加载实体:[CoPolicyPointerRedo#00502000000000] 19:14:30,985 DEBUG DefaultLoadEventListener:372 - 尝试解决:[CoPolicyPointerRedo#00502000000000] 19:14:30,985 DEBUG DefaultLoadEventListener:389 - 会话缓存中已解析的对象:[CoPolicyPointerRedo#00502000000000] 19:14:30,985 调试 TwoPhaseLoad:226 - 完成实体化 [CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=0, systemAssignId=00502000000000}] 19:14:30,985 调试 TwoPhaseLoad:130 - 解析 [CoPolicyPointerRedo#00502000000000] 的关联 19:14:30,985 DEBUG LoadContexts:218 - 创建集合包装器:[CoPolicyPointerRedo.coTransactionSummaries#00502000000000] 19:14:31,047 调试 TwoPhaseLoad:226 - 完成实体化 [CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 TwoPhaseLoad:130 - 解析 [CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=1, systemAssignId=00502000000000}] 的关联 19:14:31,047 调试 DefaultLoadEventListener:199 - 加载实体:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 DefaultLoadEventListener:372 - 尝试解决:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 DefaultLoadEventListener:389 - 会话缓存中已解析的对象:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 TwoPhaseLoad:226 - 完成实体化 [CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=1, systemAssignId=00502000000000}] 19:14:31,047 调试 TwoPhaseLoad:130 - 解析 [CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=5, systemAssignId=00502000000000}] 的关联 19:14:31,047 调试 DefaultLoadEventListener:199 - 加载实体:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 DefaultLoadEventListener:372 - 尝试解决:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 DefaultLoadEventListener:389 - 会话缓存中已解析的对象:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 TwoPhaseLoad:226 - 完成实体化 [CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=5, systemAssignId=00502000000000}] 19:14:31,047 调试 TwoPhaseLoad:130 - 解析 [CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=6, systemAssignId=00502000000000}] 的关联 19:14:31,047 调试 DefaultLoadEventListener:199 - 加载实体:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 DefaultLoadEventListener:372 - 尝试解决:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 DefaultLoadEventListener:389 - 会话缓存中已解析的对象:[CoPolicyPointerRedo#00502000000000] 19:14:31,047 调试 TwoPhaseLoad:226 - 完成实体化 [CoTransactionSummaryRedo#component[systemAssignId,transSeqId]{transSeqId=6, systemAssignId=00502000000000}] 19:14:31,047 DEBUG StatefulPersistenceContext:860 - 初始化非惰性集合 19:14:31,047 调试 JDBCContext:260 - 自动提交后 19:14:31,047 DEBUG ConnectionManager:427 - 积极释放 JDBC 连接 19:14:31,047 DEBUG SessionImpl:449 - 事务完成后

【问题讨论】:

  • 您发布的日志中唯一的查询与提供的条件不匹配。除此之外,使用systemAssignId(这是父母的PK)从孩子到CoPolicyPointerRedo的ManyToOne相当奇怪(为什么它不在父母身上?)我也觉得很奇怪上面的查询对孩子有内部连接并在ManyToOne上加入因为默认情况下两者都应该是惰性的。你在某处覆盖它吗?
  • 所以这个问题一直是火车失事......对此感到抱歉。我已将标准数据和生成的 sql 修改为我现在所拥有的。我对您断言 systemAssignId 不在父级上的声明感到困惑,它被标记为 @ID 字段。如果您指的是 @ManyToOne 关系,我使用 mappedBy 属性来指定应该如何完成映射。关于查询的最后一条语句,您是正确的,因为我强制连接发生在条件语句中。
  • 请忽略我的评论:systemAssignId - 你的标准与生成的 SQL 让我失望。我已经更新了我的答案,请看一下。

标签: hibernate jpa


【解决方案1】:

您发布的地图和您提供的描述相互冲突:

  1. 将反向关联上的连接列映射为不可插入/可更新的行不通。该列将如何更新(并维护您的父子关联)?
  2. 您的子映射将 Child 的 PK 定义为 childId(使用 @Id 注释)。这不是复合键的映射方式; Hibernate 会将 childId 视为一个简单的主键。
  3. 您的条件与您的映射(ParentTable 与 Parent 等)不匹配,这可能是一个转换工件,但除此之外看起来还可以。

不过,我会使用别名:

Criteria criteria = session.createCriteria(Parent.class)
 .add(Restrictions.eq("policyNo", "1234"))
 .createAlias("child", "children")
 .add(Restrictions.ne("children.transType", "VIEW"));

更新(基于标准/生成的 SQL):

查看 Hibernate 根据您的标准生成的 SQL(为便于阅读而缩短):

SELECT this_.*, ts1_.*, copolicypo4_.*
  FROM CoPolicyPointer this_
 INNER JOIN CoTransactionSummary ts1_ ON this_.systemAssignId=ts1_.systemAssignId
  LEFT JOIN CoPolicyPointer copolicypo4_ ON ts1_.systemAssignId=copolicypo4_.systemAssignId

您会注意到您的“父”表 (CoPolicyPointer) 被 两次 连接,即使您的条件仅连接“子”表。发生这种情况是因为您在 @Entity 注释中指定了实体名称,但使用 original 类名创建了您的条件,这使 Hibernate 认为您正在加入三个独立的实体:

  1. 标准基于CoPolicyPointerRedo.class
  2. 加入CoTransactionSummaryRedo.class,其实体名称为CoTransactionSummary
  3. 以 ``CoPolicyPointerusing@ManyToOne` 的形式返回到CoPolicyPointerRedo.class

你需要与命名保持一致。从@Entity 声明中删除name(您可以使用@Table 代替指定表名)或使用session.createCriteria(String entityName) 方法创建您的条件,该方法将实体名称而不是类名称作为参数。

【讨论】:

  • 我已按照建议从注释中删除了 insertable=false 和 updatable=false 。关于你的第二点,你是正确的@ID 注释不正确,我的代码实际上有@EmbeddedId。我不得不创建一个单独的示例,因为我不应该在互联网上共享公司代码并且没有意识到我使用了错误的注释。对困惑感到抱歉。我将标准代码更改为您上面的代码,但我仍然返回 3 个父对象,而不是仅 1 个附加子记录。还有其他想法吗?
  • 我对“不共享代码”表示同情,但我不认为只发布相关片段(并像您那样更改实体名称)会令人反感 - 否则很难在没有看到的情况下提出解决方案确切的问题。您提到的@EmbeddedId 应该(是?)应用于另一个(组件)类。 cihld 的复合 id 部分是如何分配的?您是否在 Hibernate 中启用了 SQL 输出?如果是这样,会生成什么查询?根据您的数据,它看起来是否合理,或者您是否发现有明显错误?
  • 我已经尝试了你的建议,但我仍然在 SQL 的末尾附加了一个额外的左外连接。通过将以下内容添加到条件语句中,我能够获得不同的结果:条件 .setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);但是,这不太理想,因为所有记录都是从数据库返回的,hibernate 必须确定要使用哪个记录,所以我仍然想找到另一个选项。
  • 存在左外连接是因为您正在查询子项——否则您会怎么做呢?但是,在这种情况下,您返回的“父”实例应该都是相同的,因此将转换器应用于结果是正确的方法。
  • 在查询中,休眠首先在 CoPolicyPointer 和 CoTransactionSummary 之间进行内部联接,然后在相同的两个表之间再次进行左外部联接。第二个查询不是多余的吗?另外,为什么它会返回多个父实体,一对没有孩子,而第三个确实有预期的子记录。我知道父表中只有一条记录与条件匹配,然后是 3 条 CoTransactionSummary 记录。我希望休眠返回一个带有 3 个子实体的父实体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 2014-05-28
  • 2011-08-01
  • 1970-01-01
相关资源
最近更新 更多