JPA:组合两个表时使用内部连接

时间:2016-09-04 17:32:12

标签: java hibernate

关注previous question

我有一个由下面的类映射的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;
  ...
}

(博士班级类似于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填充此对象失败,所以我编写了以下代码而没有任何连接,看起来Hibernate隐式创建了连接:

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

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

它应该是实体类吗?

我应该以某种方式用fetch / join映射它吗?

1 个答案:

答案 0 :(得分:0)

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

这里有一个关于如何使用crietria API连接“走”到相关对象属性的示例: https://stackoverflow.com/a/13856999/1527544

甚至更好: https://stackoverflow.com/a/3427661/1527544