我有两个实体,其中FSAK_Nachricht
与FNACHRICHTAKTSTATUS
存在@OneToOne
的关系。
@Entity
@Table(name = "FSAK_NACHRICHT")
public class FsakNachricht implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name = "FSAK_NACHRICHT_FNNR_GENERATOR", sequenceName = "SEQ_FSAK_NACHRICHT", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FSAK_NACHRICHT_FNNR_GENERATOR")
@Column(name = "FN_NR", unique = true, nullable = false, updatable = false)
private long fnNr;
// one-to-one association to FNachrichtAktStatus
@OneToOne
@JoinColumn(name = "FN_NR")
private FNachrichtAktStatus fnachrichtAktStatus;
// Other attributes, Getter / Setter
}
@Entity
@Table(name = "FNACHRICHTAKTSTATUS")
public class FNachrichtAktStatus implements Serializable {
private static final long serialVersionUID = 1L;
@OneToOne
@Id
@JoinColumn(name = "FN_NR", referencedColumnName = "FN_NR")
private FsakNachricht fsakNachricht;
@Column(name = "FN_AKTSTATUS", length = 30)
private String fnAktStatus;
// Getter / Setter
}
我想要做的是从
FSAK_Nachricht
中加载一条记录,并使用一个查询获取 FNACHRICHTAKTSTATUS
。因此,我编写了以下条件语句:CriteriaBuilder builder = this.getCriteriaBuilder();
CriteriaQuery<FsakNachricht> criteriaQuery = builder.createQuery(FsakNachricht.class);
Root<FsakNachricht> rootFsakNachricht = criteriaQuery.from(FsakNachricht.class);
Join<FsakNachricht, FNachrichtAktStatus> joinFNachrichtAktStatus = (Join<FsakNachricht, FNachrichtAktStatus>) rootFsakNachricht.fetch(
FsakNachricht_.fnachrichtAktStatus);
// I also join some other tables
Predicate wherePrimaryKey = builder.equal(rootFsakNachricht.get(FsakNachricht_.fnNr), primaryKey);
criteriaQuery.where(wherePrimaryKey);
List<FsakNachricht> result = this.findByCriteriaQuery(criteriaQuery);
这导致以下语句,看起来对我来说非常完美 - 除了将投影作为
@OneToOne
表的属性未列出。2020-01-22T15:00:15,358 DEBUG [AThreadPool : 2] o.h.SQL:92 -
select
fsaknachri0_.FN_NR as FN_NR1_11_0_,
// Other attributes of fsaknachri0_
// Attributs of nachrichta2_
// attributes of user tables
//
// !!!
// But none of fnachricht1_
from
FSAK_NACHRICHT fsaknachri0_
inner join
FNACHRICHTAKTSTATUS fnachricht1_
on fsaknachri0_.FN_NR=fnachricht1_.FN_NR
inner join
NACHRICHTART nachrichta2_
on fsaknachri0_.NRART_NR=nachrichta2_.NRART_NR
inner join
USER user3_
on fsaknachri0_.FN_U1=user3_.U_NR
left outer join
USER user4_
on fsaknachri0_.FN_U2=user4_.U_NR
left outer join
USER user5_
on fsaknachri0_.FN_U3=user5_.U_NR
where
fsaknachri0_.FN_NR=<KEY>
因此,另一个查询被发出。
2020-01-22T15:22:44,244 DEBUG [AThreadPool : 1] o.h.SQL:92 -
select
fnachricht0_.FN_NR as FN_NR2_7_0_,
fnachricht0_.FN_AKTSTATUS as FN_AKTSTATUS1_7_0_
from
FNACHRICHTAKTSTATUS fnachricht0_
where
fnachricht0_.FN_NR=?
我该如何避免额外的查询并使用想要的单个语句获取数据(列
fnAktStatus
)?
进一步问题:为什么我不能使用this.findByCriteriaQuerySingelResult(criteriaQuery);
(当使用Hibernate时,即使在SQLDeveloper中执行生成的查询产生了完全一行,Hibernate也无法找到任何行)。Hibernate 5.2.18(最后支持JPA 2.1)
EAGER
是JPA的默认设置,而LAZY
在@OneToOne
引用上不起作用。但无论使用哪种注解,我都希望通过显式查询来加载该值。 - bish