Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 休眠忽略左连接_Java_Hibernate - Fatal编程技术网

Java 休眠忽略左连接

Java 休眠忽略左连接,java,hibernate,Java,Hibernate,我有一个名为SecurityContact的表,它与另一个表Contacts具有多对一关系。它有两个连接到联系人的列,一个称为agentContact,另一个称为auditContact。我正在尝试运行以下HQL查询: SELECT sc FROM SecurityContact sc LEFT JOIN sc.agentContact ac LEFT JOIN sc.auditContact ac2 WHERE sc.securityId=:securityId2 但是,Hibernate完

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

SELECT sc FROM SecurityContact sc LEFT JOIN sc.agentContact ac LEFT JOIN sc.auditContact ac2 WHERE sc.securityId=:securityId2
但是,Hibernate完全忽略左连接语句,并继续生成利用内部连接的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=?
你看起来很不稳定。试试这个:

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

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

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

我创建了一个示例项目,在上一次演示了这一点

在我的示例项目中,
Employee
类具有:

在单元测试中,有一个测试是
Employee.team
引用的,另一个测试是在DB表中断言
Employee.team

此外,
公司
员工
实体之间存在类似的双向关系,并进行了类似的测试

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

DEBUG org.hibernate.SQL-选择employee0.id作为id1\u 2\u,employee0.company\u id作为company6\u 1\u 2\u,employee0\u.dateOfBi2\u 1\u 2\u,employee0\u.employmentStartDate作为employee3\u 1\u 2\u,employee0\u.firstName作为firstName1\u 2\u,employee0\u.lastName作为lastName作为lastName1\u 2\u,employee0\u.team\u团队id作为employee0,公司名称为name0\u 0\u,团队id为id2\u 1\u,团队名称为name2\u 1\u
来自雇员的信息0\ubr> 左外部加入员工上的公司1。公司id=公司1。id
左外部加入员工0上的团队2。团队id=团队2。id,其中员工0。id=


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

如果Hibernate在这里使用左连接,为什么重要?您试图用HQL查询回答什么问题?与SecurityContact中securityId=??@matt的简单
相比,您希望得到什么不同?这很重要,因为我希望Hibernate返回条目,即使没有相应的agentContact或auditContact可用。对于内部联接,它不会这样做。但是那些
@ManyToOne
关联在默认情况下不是可选的/可为空的吗?在另一个类中,这种关系的反面看起来像什么?你是说一个简单的
session.get(SecurityContact.class,securityId)
不会返回任何字段为null的实例吗?@matt它们在默认情况下确实是可选的/可为null的,这就是为什么这个问题对我来说如此奇怪。与我在代码中的注释相反,这是一种单向关系。无法从联系人联系到SecurityContact。当SecurityContact中的agentContact或auditContact为null(或设置为联系人表中不存在的值)时,Hibernate将不会提取记录。仅为了验证,您是否可以捕获生成的SQL对于简单的get-like
会话的外观。get(SecurityContact.class,id)
,来自SecurityContact的hql,其中securityId=?
和您的左连接尝试?另外,您使用的是什么版本的Hibernate?无论出于何种原因,Hibernate在使用您的查询构建annotated.xml时会抛出错误。它基本上告诉我annotated.xml文件无法构建。我发现当Hibernate不喜欢查询时会发生这种情况。我使用的是3.4.0版。
/**
 * Unidirectional relationship between Employee and Team.
 */
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;