2007-12-05
Hibernate 隐含关联(implicit joins)的变化
前一个关于这个问题的帖子被隐藏了,这次说明确些。
例如有两个类,员工TestEmployee 和部门TestDept,它们是ManyToOne关系:
现在我要查询员工A所在的部门,使用隐含关联:
如果使用Hibernate3.2.3以后的版本,会出现一个异常illegal attempt to dereference collection。这个问题比较容易解决,只需要明确的关联上employees即可:
可是,如果使用Hibernate3.2.2,即使使用隐含关联也不会有问题。我的问题是:现在升级为Hibernate3.2.5,以前的代码怎么办?这是Hibernate的Bug吗?
从Hibnerate的Jira上终于得到了答案:
对于implicit joins,Hibernate3.2.2会自动生成inner join,这样,被关联对象如果为null,就不会查出任何结果。这使得隐含关联更具确定性(原文:This makes implicit joins more deterministic. )。
Hibernate3.2.2之后如果隐含关联的是一个Collection,那么Hibernate就会抛出那个异常。这会提醒用户,使用更加明确的关联。
终于弄清问题所在了,可是以前的代码都得改,JUnit测出了40多个Bugs,郁闷呀!
例如有两个类,员工TestEmployee 和部门TestDept,它们是ManyToOne关系:
@Entity
@Table(name = "test_employees", uniqueConstraints = { })
public class TestEmployee extends BaseModel implements Serializable {
private Integer id;
private TestDept dept;
@Id
@GeneratedValue(generator = "hilo")
@GenericGenerator(name = "hilo", strategy = "hilo")
@Column(name = "ID", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(cascade = { }, fetch = FetchType.LAZY)
@JoinColumn(name = "dept_id")
public TestDept getDept() {
return this.dept;
}
public void setDept(TestDept dept) {
this.dept = dept;
}
}
@Entity
@Table(name = "test_depts", uniqueConstraints = { })
public class TestDept extends BaseModel implements Serializable {
private Integer id;
private String name;
private Set<TestEmployee> employees = new HashSet<TestEmployee>(0);
@Id
@GeneratedValue(generator = "hibseq")
@GenericGenerator(name = "hibseq", strategy = "hilo")
@Column(name = "ID", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(cascade = { }, fetch = FetchType.LAZY, mappedBy = "dept")
public Set<TestEmployee> getEmployees() {
return this.employees;
}
public void setEmployees(Set<TestEmployee> employees) {
this.employees = employees;
}
}
现在我要查询员工A所在的部门,使用隐含关联:
getHibernateTemplate().find(
"from TestDept d where d.employees.name = 'A'");
如果使用Hibernate3.2.3以后的版本,会出现一个异常illegal attempt to dereference collection。这个问题比较容易解决,只需要明确的关联上employees即可:
getHibernateTemplate().find(
"from TestDept d inner join d.employees e where e.name = 'A'");
可是,如果使用Hibernate3.2.2,即使使用隐含关联也不会有问题。我的问题是:现在升级为Hibernate3.2.5,以前的代码怎么办?这是Hibernate的Bug吗?
从Hibnerate的Jira上终于得到了答案:
对于implicit joins,Hibernate3.2.2会自动生成inner join,这样,被关联对象如果为null,就不会查出任何结果。这使得隐含关联更具确定性(原文:This makes implicit joins more deterministic. )。
Hibernate3.2.2之后如果隐含关联的是一个Collection,那么Hibernate就会抛出那个异常。这会提醒用户,使用更加明确的关联。
终于弄清问题所在了,可是以前的代码都得改,JUnit测出了40多个Bugs,郁闷呀!
评论
cats_tiger
2007-12-05
Readonly 写道
你给的代码:
Hibernate从来没有说过HQL可以这样用,因为employees是TestDept对应的一个集合,集合没有name这个属性。
在3.1~3.2中某几个版本有bug,能够让你这样的查询能生效,如果你要升级,只能一个一个地修改了。
你昨天被隐藏帖子说的是类似这样的查询:
这样的HSQL是一直可以生效的,不会出现你说的问题。
getHibernateTemplate().find("from TestDept d where d.employees.name = 'A'");
Hibernate从来没有说过HQL可以这样用,因为employees是TestDept对应的一个集合,集合没有name这个属性。
在3.1~3.2中某几个版本有bug,能够让你这样的查询能生效,如果你要升级,只能一个一个地修改了。
你昨天被隐藏帖子说的是类似这样的查询:
getHibernateTemplate().find("from TestEmployee e where e.testDept.name = 'B'");
这样的HSQL是一直可以生效的,不会出现你说的问题。
是的,这个问题困扰我很久了,所以昨天又问了一次,还吧代码贴错了,惭愧。
Readonly
2007-12-05
你给的代码:
Hibernate从来没有说过HQL可以这样用,因为employees是TestDept对应的一个集合,集合没有name这个属性。
在3.1~3.2中某几个版本有bug,能够让你这样的查询能生效,如果你要升级,只能一个一个地修改了。
你昨天被隐藏帖子说的是类似这样的查询:
这样的HSQL是一直可以生效的,不会出现你说的问题。
getHibernateTemplate().find("from TestDept d where d.employees.name = 'A'");
Hibernate从来没有说过HQL可以这样用,因为employees是TestDept对应的一个集合,集合没有name这个属性。
在3.1~3.2中某几个版本有bug,能够让你这样的查询能生效,如果你要升级,只能一个一个地修改了。
你昨天被隐藏帖子说的是类似这样的查询:
getHibernateTemplate().find("from TestEmployee e where e.testDept.name = 'B'");
这样的HSQL是一直可以生效的,不会出现你说的问题。
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 93161 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
扩展Dojo 0.9之Resizable ...
在1.1.1下无法运行
-- by mybird -
让ecside2离开prototype. ...
我也是用JQuery的 谢谢了
-- by wuhui -
Jquery终于有两个看得过去 ...
stworthy 写道JQUERY的很多插件风格都不统一,不象EXT有统一的样式 ...
-- by ayeah -
Jquery终于有两个看得过去 ...
JQUERY的很多插件风格都不统一,不象EXT有统一的样式控制及操作风格。
-- by stworthy -
Jquery终于有两个看得过去 ...
jqgrid太臃肿,我放弃了,还是选择了flexigrid,功能虽然简单,也没有 ...
-- by ayeah






评论排行榜