问题
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
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.
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).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