【问题标题】:One to one relationship hibernate results in many queries一对一关系休眠导致许多查询
【发布时间】:2023-03-17 18:22:02
【问题描述】:

我在一对一的关系中有以下课程

@Entity
@Table(name = "PERSON")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "PERSON_ID")
    private int personId;
    @Column(name = "PERSON_NAME", nullable = false, length = 30)
    private String personName;
    @OneToOne(mappedBy = "person", cascade = CascadeType.ALL)
    private DrivingLicense drivingLicense;
}

@Entity
@Table(name = "DRIVING_LICENSE")
public class DrivingLicense {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "LICENSE_NUMBER")
    private int licenseNumber;
    @Column(name = "DATE_OF_ISSUE")
    private Date dateOfIssue;
    @OneToOne
    @JoinColumn(name = "PERSON_ID", unique = true)
    private Person person;
}

目前每张表有3行

但是当我对person 进行如下查询时

Query query = entityManager.createQuery("from Person p");

在获取结果列表后,会导致以下查询过多;

Hibernate: select person0_.PERSON_ID as PERSON_ID1_1_, person0_.PERSON_NAME as PERSON_NAME2_1_ from PERSON person0_
Hibernate: select drivinglic0_.LICENSE_NUMBER as LICENSE_NUMBER1_0_1_, drivinglic0_.DATE_OF_ISSUE as DATE_OF_ISSUE2_0_1_, drivinglic0_.PERSON_ID as PERSON_ID3_0_1_, person1_.PERSON_ID as PERSON_ID1_1_0_, person1_.PERSON_NAME as PERSON_NAME2_1_0_ from DRIVING_LICENSE drivinglic0_ left outer join PERSON person1_ on drivinglic0_.PERSON_ID=person1_.PERSON_ID where drivinglic0_.PERSON_ID=?
Hibernate: select drivinglic0_.LICENSE_NUMBER as LICENSE_NUMBER1_0_1_, drivinglic0_.DATE_OF_ISSUE as DATE_OF_ISSUE2_0_1_, drivinglic0_.PERSON_ID as PERSON_ID3_0_1_, person1_.PERSON_ID as PERSON_ID1_1_0_, person1_.PERSON_NAME as PERSON_NAME2_1_0_ from DRIVING_LICENSE drivinglic0_ left outer join PERSON person1_ on drivinglic0_.PERSON_ID=person1_.PERSON_ID where drivinglic0_.PERSON_ID=?
Hibernate: select drivinglic0_.LICENSE_NUMBER as LICENSE_NUMBER1_0_1_, drivinglic0_.DATE_OF_ISSUE as DATE_OF_ISSUE2_0_1_, drivinglic0_.PERSON_ID as PERSON_ID3_0_1_, person1_.PERSON_ID as PERSON_ID1_1_0_, person1_.PERSON_NAME as PERSON_NAME2_1_0_ from DRIVING_LICENSE drivinglic0_ left outer join PERSON person1_ on drivinglic0_.PERSON_ID=person1_.PERSON_ID where drivinglic0_.PERSON_ID=?

显然是为了获取 3 行 hibernate 触发了 4 个查询,如何解决这个问题?我在人际关系方面做错了吗?

更新

现在,如果我拿驾照来拿,比如

Query query = entityManager.createQuery("from DrivingLicense dl");

更糟糕的是,触发了 7 个查询。

【问题讨论】:

  • 您不仅应该显示实体之间的关系,还应该显示整个实体类。因为ID 列对于答案并非不重要。
  • @SubOptimal 添加了 id 列

标签: java oracle hibernate


【解决方案1】:

要拥有独立于 JPA 供应商的解决方案,您可以使用以下 JPQL 查询。

使用DrivingLicense 获取所有Person

Query query = entityManager.createQuery("from Person p join fetch p.drivingLicense");

如果他们有DrivingLicense,则获取所有Person独立

Query query = entityManager.createQuery("from Person p left join fetch p.drivingLicense");

或使用Criteria API

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<Person> root = criteriaQuery.from(Person.class);
root.fetch("drivingLicense", JoinType.INNER);
criteriaQuery.select(root);
List<Person> resultList = em.createQuery(criteriaQuery).getResultList();

分别

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<Person> root = criteriaQuery.from(Person.class);
root.fetch("drivingLicense", JoinType.LEFT);
criteriaQuery.select(root);
List<Person> resultList = em.createQuery(criteriaQuery).getResultList();

【讨论】:

    【解决方案2】:

    这似乎是由于您的查询,即

    Query query = entityManager.createQuery("from Person p");
    

    改为使用:

    session.createCriteria();
    

    这只会触发 1 个查询来获取 Person:

    Hibernate:选择 this_.id 作为 id1_1_1_,this_.name 作为 name2_1_1_, drivinglic2_.id 作为 id1_0_0_,drivinglic2_.DL_no 作为 DL_no2_0_0_, drivinglic2_.PERSON_ID 作为 PERSON_I3_0_0_ 来自 PERSON this_ 左外 在 this_.id=drivinglic2_.PERSON_ID 上加入 DRIVING_LICENSEdrivinglic2_ 按 this_.id asc 排序

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多