JPA + HIBERNATE:多对多关系中的笛卡尔积

时间:2016-01-27 17:47:54

标签: jpa many-to-many jpql cartesian-product java-persistence-api

我试着解释这个问题。我有一个具有ManyToMany关系的实体

@Entity
@Table(name="TABLE1")
public class Table1 implements Serializable {

...

//bi-directional many-to-many association to Table1
@ManyToMany
@JoinTable(
    name="TABLE2"
    , joinColumns={
        @JoinColumn(name="ID_ELEMENTS1")
        }
    , inverseJoinColumns={
        @JoinColumn(name="ID_ELEMENTS2")
        }
    )
private List<Table1> elements;

//bi-directional many-to-many association to Table1
@ManyToMany(mappedBy="elements")
private List<Table1> elementOf;

...

}

Db表是:

TABLE1
ID      ...
55499   ...
55498   ...
55497   ...

TABLE2
ID_ELEMENTS1    ID_ELEMENTS2
55499           55498
55499           55497

当我尝试执行以下jpql查询

SELECT  
    t  
FROM  
    Table1 t  
    LEFT JOIN FETCH t.elementOf 
WHERE  
    t.id = 55499

结果是一个带有两个元素(具有id 55499)的arraylist,并且每个元素都有两个元素的arraylist(一个id为55498,另一个id为55497)。我想要获得的结果是一个元素(ID为55499),其中包含两个元素的arraylist(一个id为55498,另一个id为55497)。 我希望我很清楚。你能帮我优化一下java对象的结果吗(我依旧记得eclipselink中的QueryHints.BATCH)?

1 个答案:

答案 0 :(得分:1)

您已在查询中指定了join,这就是执行的内容。 JPA提供程序不会自动删除重复项。

您只需在查询中添加distinct即可删除任何重复项:

SELECT  
    DISTINCT t  
FROM  
    Table1 t  
    LEFT JOIN FETCH t.elementOf 
WHERE  
    t.id = 55499