Query dsl returning duplicate records on @one to many association(leftJoin vs leftJoin.fetch vs fetchAll)

爷,独闯天下 提交于 2019-12-12 02:50:37

问题


Here is my scenario: i have person entity which looks like below.

@Entity     
    public class Person{
     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        private Set<PhoneNumber> phoneNumbers = new HashSet<>(0);
     @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "AGENCY_ID")
        private Agency agency;

I am unable to retrieve correct data,when i query for persons. Problems i have :

1. duplicate records.
2. person with no agency not returning .
3. Bad performance

Here is what i tried, and see combination of above problems

  1. query.from(qPerson).leftJoin(qPerson.phoneNumbers, telecommNumber).leftJoin(qPerson.agency,qAgency);

I have problem 1: which is obvious(in one-to-many relationship) and this can be solved in direct hibernate by using distinct(). I tried distinct in queryDsl and that doesnt seem to work well.

  1. query.from(qPerson).leftJoin(qPerson.phoneNumbers, telecommNumber).fetch().leftJoin(qPerson.agency,qAgency).fetch(); I have problem 3 in this case: returns results correctly but performance is really bad.(Cartesian product problem, i guess).

  2. query.from(qPerson).fetchAll();

I have problem 2 in this case :This one performs well, but doesnt return person without agency when i try to sort on agency field for example. But returns that person if i dont add below to the query.

 query.orderBy(person.agency.agencyIdentifierDescription.asc());

I am trying to arrive at a solution that solves above three problems. Thanks for your help.


回答1:


Well, you should define your entities as following:

"In JPA a ManyToOne relationship is always (well almost always) required to define a OneToMany relationship, the ManyToOne always defines the foreign key (JoinColumn) and the OneToMany must use a mappedBy to define its inverse ManyToOne."

from Wiki:

ManyToOne

OneToMany

example:

public class Person {

    @ID
    private Integer id;

    @OneToMany(mappedBy = "person")
    private Set<PhoneNumber> = phoneNumbers;

    @ManyToOne
    @JoinTable(name="agency_person", joinColumns={@JoinColumn(name="person_id", referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="agency_id", referencedColumnName="id")})
    private Agency agency;

    //Getters & Setters
}

//---------------------------------------------------

public class PhoneNumber {

    @ID
    private Integer id;

    @ManyToOne
    @JoinTable(name="phonenumber_person", joinColumns={@JoinColumn(name="phone_id", referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="person_id", referencedColumnName="id")})
    private Person person;

    //Getters & Setters
}

//---------------------------------------------------

public class Agency {

    @ID
    private Integer id;

    @OneToMany(mappedBy = "agency")
    private Set<Person> persons;
    //Getters & Setters
}


来源:https://stackoverflow.com/questions/35420948/query-dsl-returning-duplicate-records-on-one-to-many-associationleftjoin-vs-le

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!