Question

I have googled but haven't found proper answer. I use JPA and Spring Data JPA. I have mapped parent table with child table, where the join column is in child table. So in my parent table there is a reference mappedBy and I do the JPA query for the parent entity and instead of it returning only 1, it returns it as many as there are child entities. Here is example:

My tables very simplified

Parent

| ID |       COLUMN_A |
|----|----------------|
|  1 | Column A value |  

Child
| ID |   CHILD_COLUMN_A | PARENT_ID |
|----|------------------|-----------|
|  1 | Child column A 1 |         1 |
|  2 | Child column A 2 |         1 |
|  3 | Child column A 3 |         1 |

Native query I do that return what i want:
SELECT * FROM parent p INNER JOIN child c ON p.id = c.parent_id

| ID |   CHILD_COLUMN_A | PARENT_ID |
|----|------------------|-----------|
|  1 | Child column A 1 |         1 |
|  2 | Child column A 2 |         1 |
|  3 | Child column A 3 |         1 |

My entity mappings are following:

@Entity
@Table(name = "parent")
public class Parent implements Serializable{
    ...
    @OneToMany(mappedBy="parent", cascade = CascadeType.PERSIST)
    List<child> children = new ArrayList<>();
        ...
}

@Entity
@Table(name = "child")
public class Child implements Serializable{
    ...
    @ManyToOne
    @JoinColumn(name = "parent_id")
    private Parent parent;
        ....
}

My annotated query in the ParentRepository class is as follows:

@Query("SELECT p FROM Parent p INNER JOIN FETCH p.children c")
public Collection<Parent> getAll();

So with above query I get returned a Collection with 3 Parent objects, instead of 1! And in each Parent object is correctly 3 'Child' objects as supposed to be. So question is why does it return Parent same amount as it has Child in it? I can look at the generated SQL, but it doesn't help me much by just seeing it. Other thing I can add distinct:

SELECT DISTINCT p FROM Parent p INNER JOIN FETCH p.children c

but then again, it's not optimized, cause it first gets excessive Parent objects with Child and then narrows down to one. What if I would have 1000 Child objects, then it would produce 1000 Parent objects which would be really overwhelming.

I'm sure this is common problem, but I couldn't find anything, there was only Hibernate specific answer to use FetchType.SUBSELECT, but it didn't change results. Any help is appreciated, thank you.

Était-ce utile?

La solution

Use the DISTINCT keyword as you described without worrying, because it is the database layer's problem to do that effectively. Also, you might consider removing the INNER JOIN with the children if you do not have any conditions in the query (that you did not show).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top