一对多关系使用左联接获取重复对象

时间:2018-09-03 19:18:53

标签: java hibernate jpa

我在一对多关系中有2个类,并且一个JPQL查询现在可以按预期工作。即使在阅读了一些有关它的帖子后,对我来说仍然不清楚。

@Entity
@Table(name = "context_entity")
public class ContextEntity {
    @Id
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinColumn(name = "entity_id")
    private List<TypeSpecCharacteristicValue> metadata = null;
}

@Entity
@Table(name = "type_spec_characteristic_value")
public class TypeSpecCharacteristicValue {
    @Id
    private Long id;

    private String value;
}

顺便说一句,我只剪切了代码的重要部分。

如果运行以下查询,则会得到重复的TypeSpecCharacteristicValue对象:

session.createQuery("select e.metadata from ContextEntity e left join e.metadata where e.id=:contextId")

然后我检查hibernate生成的SQL语句,结果如下:

select metadata2_.id as id1_5_, metadata2_.value as value3_5_ from context_entity contextent0_ left outer join type_spec_characteristic_value metadata1_ on contextent0_.id=metadata1_.entity_id inner join type_spec_characteristic_value metadata2_ on contextent0_.id=metadata2_.entity_id where contextent0_.id=[some_context_id];

为什么Hibernate与表type_spec characteristic_value生成第二个联接?我应该使用不同的东西吗?

谢谢。

2 个答案:

答案 0 :(得分:0)

我猜想第二个(内部)连接隐式地来自以下语句:

select e.metadata from ContextEntity e..

通过在实体上使用点运算符,您可以调用表之间的关系,因为您还需要另一个表中的所有字段。

答案 1 :(得分:0)

也许我陷入了JPA的一个非常普遍的误解。

根据我对Hibernate FAQsthis问题的理解,这与我的发现有一些相似之处,这是JPA的预期行为,因此有必要使用其他资源来消除结果中的重复项。

尽管有这种行为,我发现通过查询中的以下优化,避免了第二次JOIN,并且没有重复的结果。

callback(null, { "statusCode": 200, "body" : JSON.stringify(sampleResponseJSON) }); on lambda `js`

现在生成的查询结果为:

select m from ContextEntity e left join e.metadata m where e.id=:contextId

我猜想在联接右侧使用别名会以某种方式告诉休眠状态,以便直接获取元数据对象,因此应用了一些优化。