繁体   English   中英

JPA:合并两个表时使用内部联接

[英]JPA: Using Inner Joing when Combining Two Tables

在上一个问题之后

我有一个由以下类映射的Patients表:

public class Patient {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int uid;
  @Column(columnDefinition = "VARCHAR(20)")
  private String id;
  private boolean isId;
  private String name;
  @ManyToOne
  @JoinColumn(name="hmo")
  private Hmo hmo;
  @ManyToOne
  @JoinColumn(name="doctor")
  private Doctor doctor;
  private Instant openDate;
  private String comments;
  ...
}

以及由以下类映射的HMO表:

public class Hmo {

  public static final String UID = "uid";
  public static final String NAME = "name";

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int uid;
  private String name;
  ...
}

(Doctor类类似于HMO)我只想提取患者的一个子集:其ID,名称和HMO的名称,因此我创建了一个元数据对象:

public class PatientMetadata {

  public static final String UID = "uid";
  public static final String NAME = "name";

  private int uid;
  private String id;
  private boolean isId;
  private String name;
  private String hmo;
  ...
}

尝试使用join和fetch填充此对象失败,因此我编写了以下没有任何join的代码,并且看起来Hibernate隐式创建了join:

try (SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
         Session session = sessionFactory.openSession()) {
      CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
      CriteriaQuery<PatientMetadata> criteria = criteriaBuilder.createQuery(PatientMetadata.class);
      Root<Patient> patientRoot = criteria.from(Patient.class);
      Root<Hmo> hmoRoot = criteria.from(Hmo.class);
      criteria.select(criteriaBuilder.construct(PatientMetadata.class,
                                                patientRoot.get("uid"),
                                                patientRoot.get("id"),
                                                patientRoot.get("isId"),
                                                patientRoot.get("name"),
                                                hmoRoot.get("name")))
              .where(criteriaBuilder.equal(patientRoot.get("hmo"), hmoRoot.get("uid")));
      System.out.println(session.createQuery(criteria).getResultList());
}

看起来代码运行良好:我得到了正确的答案,并且只有一个SQL查询发送到服务器。
问题在于所生成的SQL查询包含交叉Hibernate: select patient0_.uid as col_0_0_, patient0_.id as col_1_0_, patient0_.isId as col_2_0_, patient0_.name as col_3_0_, hmo1_.name as col_4_0_ from patients patient0_ cross join hmos hmo1_ where patient0_.hmo=hmo1_.uid而不是内部Hibernate: select patient0_.uid as col_0_0_, patient0_.id as col_1_0_, patient0_.isId as col_2_0_, patient0_.name as col_3_0_, hmo1_.name as col_4_0_ from patients patient0_ cross join hmos hmo1_ where patient0_.hmo=hmo1_.uidHibernate: select patient0_.uid as col_0_0_, patient0_.id as col_1_0_, patient0_.isId as col_2_0_, patient0_.name as col_3_0_, hmo1_.name as col_4_0_ from patients patient0_ cross join hmos hmo1_ where patient0_.hmo=hmo1_.uid

但是,根据文档,不建议使用此类查询(使用WHERE的CROSS JOIN),所以我的问题是如何正确正确地填充此元数据对象?

应该是实体类吗?

我应该以某种方式将其映射为访存/加入吗?

这很可能是因为您使用2个不同的根。 尝试使用一个根,例如。 扎根并从那里步行到HMO。 您的结果需要来自Patient和HMO的数据,那么为什么没有内部连接它们呢?

在这里,您有一个示例,说明如何使用crietria API联接“漫游”到相关对象的属性: https ://stackoverflow.com/a/13856999/1527544

甚至更好的是这里: https : //stackoverflow.com/a/3427661/1527544

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM