查询dsl将@one上的重复记录返回给多个关联(leftJoin vs leftJoin.fetch vs fetchAll)

时间:2016-02-15 23:22:48

标签: java hibernate hql jpql querydsl

这是我的场景:我有人实体,如下所示。

@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;

当我查询人员时,我无法检索到正确的数据。 我遇到的问题:

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

这是我尝试过的,并看到上述问题的组合

  1. query.from(qPerson).leftJoin(qPerson.phoneNumbers, telecommNumber).leftJoin(qPerson.agency,qAgency);
  2. 我有问题1:这是显而易见的(在一对多的关系中),这可以通过使用distinct()在直接休眠中解决。我在queryDsl中试过了不同的东西,但似乎效果不好。

    1. query.from(qPerson).leftJoin(qPerson.phoneNumbers, telecommNumber).fetch().leftJoin(qPerson.agency,qAgency).fetch(); 在这种情况下我有问题3:正确返回结果但性能非常差。(笛卡尔积问题,我猜)。

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

    3. 在这种情况下我有问题2:这个表现不错,但是当我尝试对代理商领域进行排序时,没有代理人也没有回报。但如果我不在查询中添加以下内容,则返回该人。

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

      我正在努力找到解决上述三个问题的解决方案。谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

好吧,您应该将您的实体定义如下:

&#34;在JPA中,ManyToOne关系始终(几乎总是)需要定义OneToMany关系,ManyToOne始终定义外键(JoinColumn并且OneToMany必须使用mappedBy来定义其反ManyToOne。&#34;

来自Wiki:

ManyToOne

OneToMany

示例:

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
}