Grails hasMany 和标准没有按预期工作
Grails hasMany and criteria not working as expected
我有两个具有 hasMany 关系的模型
class Puturru implements Serializable {
String name
Set<Fua> fuas
static hasMany = [fuas: Fua]
static constraints = {
fuas(nullable: true)
}
}
和
class Fua {
String name
static constraints = {
}
}
当 运行 下一次测试时,我得到一个 LazyInitializationException
void "test something"() {
given:
def puturrus
Puturru.withNewSession { session ->
p = Puturru.build()
Fua f
for (int i = 0; i < 10; i++) {
f = Fua.build()
p.addToFuas(f)
}
f.save(failOnError: true, flush: true)
}
when:
Puturru.withNewSession {
puturrus = Puturru.createCriteria().listDistinct {
fetchMode("fuas", FetchMode.JOIN)
}
}
then:
Puturru.withNewSession {
assert puturrus.fuas*.name.size() > 0
}
p.fuas.each { it.delete() }
p.delete()
}
如果我设置 puturrus 映射
static mapping = {
fuas lazy: false
}
然后检索所有元素,尽管它使用多选,否则使用此查询
select ...
from puturru ...
left outer join puturru_fua fuas2_ on this_.id=fuas2_.puturru_fuas_id
我无法在真实应用中设置映射,因为我不想在所有情况下都获取所有条目。在我看来,我似乎遗漏了一些使标准比中间 table.
更进一步的东西
我正在使用 grails 2.3.6 和 hibernate 3.6.10.8。
有人知道为什么没有得到 "fuas" 对象吗?
编辑 1:更多信息
我一直在尝试对域进行一些更改并进行测试,以找出问题所在。
在@sudhir 建议后,我开始玩连接我将标准更改为类似
puturrus = Puturru.createCriteria().listDistinct {
fuas {
}
}
然后由 gorm 和 hibernate 生成的查询是
select ...
from puturru this_
inner join puturru_fua fuas3_ on this_.id=fuas3_.puturru_fuas_id
inner join fua fuas_alias1_ on fuas3_.fua_id=fuas_alias1_.id
这次我们得到了所有条目,但没有得到它们与 puturrus 域的关系。我们妥协并提出第二个查询只是为了获得关联,所以暂时第二个会话块是
Puturru.withNewSession {
puturrus = Puturru.createCriteria().listDistinct {
fuas {
}
}
Puturru.createCriteria().listDistinct {
fetchMode("fuas", FetchMode.JOIN)
}
}
这比我之前在标准会话中迭代所有 puturrus 和所有 fuas 的方法要好得多,但我认为仍然不是最优的,所以有什么方法可以同时获取数据和单个查询中的关联?
你可以使用下面的hql
Puturru.executeQuery("select p from Puturru p inner join fetch p.fuas as f where p.id = :id", [id:id])
如果你想让所有的Puturru去掉where条件
我们使用 createAlias 找到了合适的解决方案
Puturru.withNewSession {
puturrus = Puturru.createCriteria().listDistinct {
createAlias("fuas", "fuas", CriteriaSpecification.LEFT_JOIN)
}
}
实际上这似乎是 Hibernate 3.6 中的一个错误,已经在 Hibernate 4 中修复了
我有两个具有 hasMany 关系的模型
class Puturru implements Serializable {
String name
Set<Fua> fuas
static hasMany = [fuas: Fua]
static constraints = {
fuas(nullable: true)
}
}
和
class Fua {
String name
static constraints = {
}
}
当 运行 下一次测试时,我得到一个 LazyInitializationException
void "test something"() {
given:
def puturrus
Puturru.withNewSession { session ->
p = Puturru.build()
Fua f
for (int i = 0; i < 10; i++) {
f = Fua.build()
p.addToFuas(f)
}
f.save(failOnError: true, flush: true)
}
when:
Puturru.withNewSession {
puturrus = Puturru.createCriteria().listDistinct {
fetchMode("fuas", FetchMode.JOIN)
}
}
then:
Puturru.withNewSession {
assert puturrus.fuas*.name.size() > 0
}
p.fuas.each { it.delete() }
p.delete()
}
如果我设置 puturrus 映射
static mapping = {
fuas lazy: false
}
然后检索所有元素,尽管它使用多选,否则使用此查询
select ...
from puturru ...
left outer join puturru_fua fuas2_ on this_.id=fuas2_.puturru_fuas_id
我无法在真实应用中设置映射,因为我不想在所有情况下都获取所有条目。在我看来,我似乎遗漏了一些使标准比中间 table.
更进一步的东西我正在使用 grails 2.3.6 和 hibernate 3.6.10.8。
有人知道为什么没有得到 "fuas" 对象吗?
编辑 1:更多信息
我一直在尝试对域进行一些更改并进行测试,以找出问题所在。
在@sudhir 建议后,我开始玩连接我将标准更改为类似
puturrus = Puturru.createCriteria().listDistinct {
fuas {
}
}
然后由 gorm 和 hibernate 生成的查询是
select ...
from puturru this_
inner join puturru_fua fuas3_ on this_.id=fuas3_.puturru_fuas_id
inner join fua fuas_alias1_ on fuas3_.fua_id=fuas_alias1_.id
这次我们得到了所有条目,但没有得到它们与 puturrus 域的关系。我们妥协并提出第二个查询只是为了获得关联,所以暂时第二个会话块是
Puturru.withNewSession {
puturrus = Puturru.createCriteria().listDistinct {
fuas {
}
}
Puturru.createCriteria().listDistinct {
fetchMode("fuas", FetchMode.JOIN)
}
}
这比我之前在标准会话中迭代所有 puturrus 和所有 fuas 的方法要好得多,但我认为仍然不是最优的,所以有什么方法可以同时获取数据和单个查询中的关联?
你可以使用下面的hql
Puturru.executeQuery("select p from Puturru p inner join fetch p.fuas as f where p.id = :id", [id:id])
如果你想让所有的Puturru去掉where条件
我们使用 createAlias 找到了合适的解决方案
Puturru.withNewSession {
puturrus = Puturru.createCriteria().listDistinct {
createAlias("fuas", "fuas", CriteriaSpecification.LEFT_JOIN)
}
}
实际上这似乎是 Hibernate 3.6 中的一个错误,已经在 Hibernate 4 中修复了