Hibernate 使用左联接获取重复项

Hibernate 使用左联接获取重复项,hibernate,jpa,hql,left-join,fetch,Hibernate,Jpa,Hql,Left Join,Fetch,我正在使用HQL查询来获取某些记录。如果使用LEFT JOIN FETCH,则目标实体中的集合将包含重复记录。如果我只使用左连接,它不会。我猜当Hibernate懒洋洋地加载记录时,它会避免重复 "SELECT z FROM ", TableA.TABLE_NAME, " z ", // "LEFT JOIN FETCH z.attributeX pv ", // "LEFT JOIN FETCH pv.attributeY anteil ",

我正在使用HQL查询来获取某些记录。如果使用
LEFT JOIN FETCH
,则目标实体中的集合将包含重复记录。如果我只使用左连接,它不会。我猜当Hibernate懒洋洋地加载记录时,它会避免重复

"SELECT z FROM ", TableA.TABLE_NAME, " z ",  //
            "LEFT JOIN FETCH z.attributeX pv ", //
            "LEFT JOIN FETCH pv.attributeY anteil ", //
            "LEFT JOIN FETCH z.attributeB kma ", //
            "LEFT JOIN FETCH kma.attributeC ", //
            "WHERE anteil.attributeD.attributeE.id = :eId ", //
            "AND pv.attributeG.id = :gId ");
我的实体
TableA
有一个指向
TablePV
的链接(
LEFT JOIN FETCH z.attributeX pv

TablePV
有一组
TableY
LEFT JOIN FETCH pv.attributeY anteil


现在,Hibernate将正确映射除
TablePV
的子对象之外的所有对象。它将包含多次相同的记录。在
表A上显示一个不同的图标没有帮助,因为那里没有重复项。我想我可以手动删除那些性能相当差的记录。

尝试在查询中使用
DISTINCT
,例如
从实体z中选择DISTINCT z…
真正保证的唯一方法是在这些集合上使用
集合
排序集
,而不是使用
列表
。使用Hibernate没有其他方法可以避免此问题:

@OneToMany
private Set<AttributeY> attributeY;
以及:


如果复制在根实体
TableA
中,则
DISTINCT
将有所帮助,但这不是您的情况。

使用集合作为集合。AFAIK LEFT JOIN FETCH和对它的限制是互斥的,因为该限制可能会过滤掉集合中的元素以进行提取。也许你有不同的根本原因,谢谢你的回答。集合可以解决问题,但它是一种解决方法,并且会产生其他问题(例如,排序)。我不知道这是否是相互排斥的,因为这个案子是有道理的。我希望在同一个查询中获取记录,而不是使用另一个select语句。如果我只使用LEFT JOIN而不使用FETCH,就会发生这种情况。集合如何删除集合属性中的重复对象?!了解左联接返回的内容:内部联接行加上由null扩展的不匹配左表行。始终知道作为左连接的一部分,您需要什么样的内部连接。一个WHERE或INTERNAL ON,在左联接ON删除任何由NULL扩展的行后,要求右表列不为NULL,即只保留内部联接行,即“将左联接转换为内部联接”。你有。正如我在问题中提到的,这不起作用。问题是,集合包含重复项,而不是主实体本身。
@OneToMany
@SortNatural
private SortedSet<AttributeY> attributeY = new TreeSet<>();
@Entity
public class AttributeY implements Comparable<AttributeY> {

    @Override
    public int compareTo(AttributeY o) {
        return number.compareTo( o.getNumber() );
    }

}
LEFT JOIN FETCH z.attributeX
LEFT JOIN FETCH pv.attributeY
LEFT JOIN FETCH z.attributeB kma
LEFT JOIN FETCH kma.attributeC
LEFT JOIN pv.attributeY anteil
LEFT JOIN anteil.attributeD attributeD
LEFT JOIN attributeD.attributeE attributeE
LEFT JOIN z.attributeX pv
LEFT JOIN pv.attributeG attributeG
WHERE attributeE.id = :eId 
AND attributeG.id = :gId