我有一个由下面的类映射的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映射它吗?
答案 0 :(得分:0)
这很可能是因为你使用了2个不同的根。尝试使用一个根,例如。从那里扎根并走向HMO。您的结果需要来自Patient和HMO的数据,那么为什么没有内部加入它们?
这里有一个关于如何使用crietria API连接“走”到相关对象属性的示例: https://stackoverflow.com/a/13856999/1527544