【问题标题】:Left join in Hibernate "one to zero or one" mapping在 Hibernate “一对零或一”映射中左连接
【发布时间】:2012-01-09 06:44:22
【问题描述】:

我有两张表如下:

Student: oneID (primary key), col1, col2, col3, subId, col4
Subject: subID (primary key), col1, col2

每个学生都会有一个或没有指定的科目。

所以在这种情况下:分配的一个主题:学生中的 subId 将具有映射到主题表中的 subID 的一些值

在这种情况下:分配了 0 个主题:Student 中的 subId 将为空。

在上述情况下,我有一个左连接查询如下:

select st.col1, st.col2, su.col1, su.col2 from Student st left join Subject su on st.subId = su.subId where st.oneId = 'abc'

如何在 Hibernate 中编写完全相同的查询?

select st.col1, st.col2, su.col1, su.col2 from Student st left join st.sub as su where st.oneId = 'abc'

以上查询不起作用并给出以下错误:

"org.hibernate.hql.ast.QuerySyntaxException: Path expected for join!"

我错过了什么?

在我的 java 代码中,我让两个表保持独立。那就是定义的表之间没有关系。

Persistence.xml 如下:

<persistence-unit name="myEntityManager" transaction-type="RESOURCE_LOCAL">              
  <provider>org.hibernate.ejb.HibernatePersistence</provider>    
  <class>com.myPackage.Student</class>       
  <class>com.myPackage.Subject</class>   
</persistence-unit> 

POJO 如下:

学生

@Entity
@Table(name = "STUDENT")
public class Student implements Serializable {

@Id
@Column(name = "ONEID")
private String oneId;

private Subject sub;

//other columns here

public void setSub(final Subject sub) {
    this.sub = sub;
}

@OneToOne(cascade = CascadeType.ALL)
public Subject getSub() {
    return this.sub;
}
} 

主题

@Entity
@Table(name = "SUBJECT")
public class Subject implements Serializable {

@Id
@Column(name = "SUBID")
private String subId;

//other columns here
} 

【问题讨论】:

  • 我的疑问是,虽然主题不适用于给定的学生,但您正在投影主题属性......我认为这可能会导致 NullPointerException!
  • 你需要学生和学科之间的关系才能使用加入,而且学生看起来不像有“subId”
  • @bestsss:我在学生表 subId 中只有一个属性。当它不为空时,我们可以将它与主题表连接以获取主题详细信息。
  • 你的意思是每个学生只有一门学科吗?在任何情况下,您都需要StudentCollection&lt;Subject&gt; 中的Subject 字段,具体取决于关系。
  • 关注@yair 的回答并阅读一些教程,查看示例。

标签: java sql hibernate


【解决方案1】:

正如this hibernate forum thread 中所提到的,目前在Hibernate 中无法对未关联的实体调用左联接。还有一个opened Hibernate issue

您应该做的是在StudentSubject 之间定义one-to-oneone-to-many 关系(one-to-one examplemany-to-one example)。

然后,试试这个 HQL,假设 Student 中对其主题的引用名为 subjects

select st.col1, st.col2, su.col1, su.col2 from Student st left join st.subjects su where st.oneId = 'abc'

【讨论】:

  • 谢谢!!但是您所展示的示例清楚地表明一名学生有很多电话号码。但我的例子是学生要么有一门科目,要么没有科目..怎么做?
  • @NikunjChauhan - 编辑答案以包含一对一示例的链接(请注意,查询也应根据参考名称更改)。
  • @yair: 抱歉.. 但它仍然无法正常工作.. 我更改了我的课程并按照建议一对一添加了注释.... 请注意,我的学生和主题之间的关系是“一对一”零或一”...我仍然收到“预期加入的路径!”错误...
【解决方案2】:

由于我在映射中看不到您的模型之间的任何关联,您可以参考this 链接来解决您的问题。或者只是在您的映射中添加关联,即在学生中为主题添加多对一关联并将您的查询修改为

select st.col1, st.col2, su.col1, su.col2 from Student st left outer join st.subject as su where st.oneId = 'abc' and st.subId = su.subId

【讨论】:

  • 检查了链接..但没有得到。我想要左连接,因为当学生表中的 subId 为空时,我仍然想要我在查询中获取的学生表中的列..我不知道如何实现..
  • 试试这个而不是加入 - 从 Student st 中选择 st.col1、st.col2、su.col1、su.col2,Subject su where st.oneId = 'abc' and (st.subId = su.subId 或 st.subId 为空)
猜你喜欢
  • 1970-01-01
  • 2012-06-26
  • 2016-07-30
  • 1970-01-01
  • 2021-08-18
  • 2012-04-21
  • 1970-01-01
相关资源
最近更新 更多