gpt4 book ai didi

java - hibernate 忽略 LEFT JOIN

转载 作者:行者123 更新时间:2023-11-30 09:46:57 25 4
gpt4 key购买 nike

我有一个名为 SecurityContact 的表,它与另一个表 Contacts 具有多对一关系。它有两个连接到 Contacts 的列,其中一个称为 agentContact,另一个称为 auditContact。我正在尝试运行以下 HQL 查询:

SELECT sc FROM SecurityContact sc LEFT JOIN sc.agentContact ac LEFT JOIN sc.auditContact ac2 WHERE sc.securityId=:securityId2

但是,Hibernate 完全忽略了 LEFT JOIN 语句并继续生成利用内部连接的 SQL。这根本不符合我的目的。我试过设置获取注释但没有成功。这个问题让我发疯了两天多,所以任何帮助都将不胜感激。

这是我的 SecurityContact 类的代码:

/**
* The persistent class for the SecurityContact database table.
*
*/
@Entity
@FXClass(kind=FXClassKind.REMOTE)
public class SecurityContact implements Serializable {
private static final long serialVersionUID = 1L;
@Transient private String uid;
@FXIgnore
public String getUid() {
if (uid == null) {
uid = "" + securityContactId;
}
return uid;
}

public void setUid(String uid) {
this.uid = uid;
}

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="securityContact_id")
private Long securityContactId;

@Column(name="security_id")
private String securityId;

@Column(name="create_date")
private String createDate;

@Column(name="create_user")
private String createUser;

@Column(name="modify_date")
private String modifyDate;

@Column(name="modify_user")
private String modifyUser;

//uni-directional many-to-one association to AgentContact

@ManyToOne
@JoinColumn(name="agent_id", referencedColumnName="contact_id")
private Contact agentContact;

//uni-directional many-to-one association to AuditContact
@ManyToOne
@JoinColumn(name="audit_id", referencedColumnName="contact_id")
private Contact auditContact;

public SecurityContact() {
}
@FXKeyColumn
public Long getSecurityContactId() {
return this.securityContactId;
}

public void setSecurityContactId(Long securityContactId) {
this.securityContactId = securityContactId;
}

public String getSecurityId() {
return this.securityId;
}

public void setSecurityId(String securityId) {
this.securityId = securityId;
}

public String getCreateDate() {
return this.createDate;
}

public void setCreateDate(String createDate) {
this.createDate = createDate;
}

public String getCreateUser() {
return this.createUser;
}

public void setCreateUser(String createUser) {
this.createUser = createUser;
}

public String getModifyDate() {
return this.modifyDate;
}

public void setModifyDate(String modifyDate) {
this.modifyDate = modifyDate;
}

public String getModifyUser() {
return this.modifyUser;
}

public void setModifyUser(String modifyUser) {
this.modifyUser = modifyUser;
}
@FXManyToOne(parent="parent", property="contactId")
public Contact getAgentContact() {
return this.agentContact;
}

public void setAgentContact(Contact agentContact) {
this.agentContact = agentContact;
}
@FXManyToOne(parent="parent", property="contactId")
public Contact getAuditContact() {
return this.auditContact;
}

public void setAuditContact(Contact auditContact) {
this.auditContact = auditContact;
}

}

这是从上面的 HQL 生成的 SQL:

select securityco0_.agent_id as col_0_0_, securityco0_.audit_id as col_1_0_, securityco0_.create_date as col_2_0_, securityco0_.create_user as col_3_0_, securityco0_.modify_date as col_4_0_, securityco0_.modify_user as col_5_0_, securityco0_.securityContact_id as col_6_0_, securityco0_.security_id as col_7_0_, agentconta3_.contact_id as contact1_0_0_, agentconta4_.contact_id as contact1_0_1_, agentconta3_.bank_id as bank10_0_0_, agentconta3_.create_date as create2_0_0_, agentconta3_.create_user as create3_0_0_, agentconta3_.email as email0_0_, agentconta3_.fax as fax0_0_, agentconta3_.modify_date as modify6_0_0_, agentconta3_.modify_user as modify7_0_0_, agentconta3_.name as name0_0_, agentconta3_.phone as phone0_0_, agentconta4_.bank_id as bank10_0_1_, agentconta4_.create_date as create2_0_1_, agentconta4_.create_user as create3_0_1_, agentconta4_.email as email0_1_, agentconta4_.fax as fax0_1_, agentconta4_.modify_date as modify6_0_1_, agentconta4_.modify_user as modify7_0_1_, agentconta4_.name as name0_1_, agentconta4_.phone as phone0_1_ from SecurityContact securityco0_ left outer join AgentContact agentconta1_ on securityco0_.agent_id=agentconta1_.contact_id left outer join AgentContact agentconta2_ on securityco0_.audit_id=agentconta2_.contact_id inner join AgentContact agentconta3_ on securityco0_.agent_id=agentconta3_.contact_id inner join AgentContact agentconta4_ on securityco0_.audit_id=agentconta4_.contact_id where securityco0_.security_id=?

最佳答案

我已经针对您的问题进行了一些测试,在我看来,您的映射一定有问题,或者您正在使用的(过时的)Hibernate 版本中存在错误。

对于可选的@ManyToOne 关联,Hibernate 应该已经使用左连接来查询实体及其关联(因为这是查询根实体,无论关联实体是否为空)。

我在 https://github.com/mattnworb/hibernate-sample 上拼凑了一个示例项目来说明这一点.

在我的示例项目中,Employee 类有 a unidirectional many-to-one mapping to the Team class :

/**
* Unidirectional relationship between Employee and Team.
*/
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;

在单元测试中,Employee.team 引用is not-null when it is set in the DB 都有一个测试。 ,以及另一个断言 Employee.team is null when not set 的测试在数据库表中。

此外,CompanyEmployee 实体之间也存在类似的双向关系,具有类似的测试。

最后,在日志中我可以看到,当 Hibernate 查询 Employee 实体时(使用简单的 session.get(Employee.class, id)),它使用左连接来拉入teams 表(我自己添加了换行符):

DEBUG org.hibernate.SQL - select employee0_.id as id1_2_, employee0_.company_id as company6_1_2_, employee0_.dateOfBirth as dateOfBi2_1_2_, employee0_.employmentStartDate as employme3_1_2_, employee0_.firstName as firstName1_2_, employee0_.lastName as lastName1_2_, employee0_.team_id as team7_1_2_, company1_.id as id0_0_, company1_.name as name0_0_, team2_.id as id2_1_, team2_.name as name2_1_
from employees employee0_
left outer join companies company1_ on employee0_.company_id=company1_.id
left outer join teams team2_ on employee0_.team_id=team2_.id where employee0_.id=?

总而言之,为了让 Hibernate 在关联实体之间使用左连接,只要将关系设置为可选,就根本不需要特殊的 HQL 查询 - 一个简单的 session根实体的 .get() 应该使用左连接查询关联实体的表。如果您看到不同的结果,这表明您的 Hibernate 版本中存在错误(我在这里使用的是 3.6.6.Final),或者您的映射中存在错误。

关于java - hibernate 忽略 LEFT JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6914668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com