Grails hasMany和标准没有按预期工作

时间:2015-03-20 17:26:34

标签: grails gorm hibernate-criteria

我有两个带有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

我无法在真实应用中设置映射,因为我不想在所有情况下获取所有条目。对我来说,似乎我错过了一些东西,使标准比中间表更进一步。

我使用grails 2.3.6和hibernate 3.6.10.8。

有人知道为什么没有得到&#34; fuas&#34;对象

编辑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,但我认为仍然是次优的,所以有没有办法同时获得数据和关联单个查询?

2 个答案:

答案 0 :(得分:0)

您可以使用以下hql

Puturru.executeQuery("select p from Puturru p inner join fetch p.fuas as f where p.id = :id", [id:id])

如果你想让所有Puturru移除条件

答案 1 :(得分:0)

我们使用createAlias

找到了合适的解决方案
Puturru.withNewSession {
    puturrus = Puturru.createCriteria().listDistinct {
        createAlias("fuas", "fuas", CriteriaSpecification.LEFT_JOIN)
    }
}

实际上它似乎是已经在Hibernate 4中修复的Hibernate 3.6中的一个错误