Grails使用不产生预期结果的集合查询域类

时间:2014-10-30 22:50:08

标签: hibernate grails

(Grails 2.4.2)

我试图获取用户可以访问的故事列表。因此,用户是故事或用户的所有者的所有故事都在这个故事的编辑集合中。我尝试了很多不同的查询,从createCriteria到编写HQL。我可以查询用户所有的故事。我可以查询用户在编辑集合中的所有故事,但是当我将查询与OR一起放在一起时,我没有得到正确的结果。

class Story {
  String title
  Date dateCreated
  Date lastUpdated
  String description
  Boolean isPublic
  List storyContent = []
  User owner

    static belongsTo = [owner: User]
    static hasMany = [storyContent : StoryContent, viewers : Viewer, editors : Editor] 
...more


class Editor  { 
    User user
    static belongsTo = [story: Story]

当我执行以下查询时:

def hql = "from Story as s left outer join s.editors as se where s.owner.username = 'joe'"
def results = Story.executeQuery(hql)

我得到了正确的结果:

Result: [[com.storycreate.Story : 3, com.storycreate.Editor : 1], [com.storycreate.Story : 2, null]]

Joe是故事2和故事3的所有者。现在我查询Joe是编辑的所有故事

def hql = "from Story as s left outer join s.editors as se where se.user.username='joe'"
def results = Story.executeQuery(hql)

并获得正确的结果:(乔既是故事3的编辑和所有者,也是故事4的编辑)

Result: [[com.storycreate.Story : 3, com.storycreate.Editor : 1], [com.storycreate.Story : 4, com.storycreate.Editor : 4]]

现在,如果我将这个结合起来得到乔是所有者或编辑的故事列表:

def hql = "from Story as s left outer join s.editors as se where (s.owner.username='joe' OR se.user.username='joe')"
def results = Story.executeQuery(hql)

我得到了错误的结果(错过了故事2,其中乔是所有者)

Result: [[com.storycreate.Story : 3, com.storycreate.Editor : 1], [com.storycreate.Story : 4, com.storycreate.Editor : 4]]

最终,我希望查询能够为我提供isPublic为true的所有故事列表,或者登录用户是故事的所有者,编辑者或查看者。但我似乎错过了对Hibernate如何在这里工作的一些理解。

1 个答案:

答案 0 :(得分:0)

这个集成规范在2.4.3中传递给我:

class StoryControllerIntSpec extends IntegrationSpec {

    def setup() {
        User joe = new User(userName: "joe").save()
        User bar = new User(userName: "bar").save()
        User foo = new User(userName: "foo").save()

        // joe as both owner and editor
        Story s1 = new Story(isPublic: true, title: "Story1", owner: joe)
        Editor e1 = new Editor(user: joe)
        s1.addToEditors(e1)

        // joe only as owner
        Story s2 = new Story(isPublic: true, title: "Story2", owner: joe)
        Editor e2 = new Editor(user: foo)
        s2.addToEditors(e2)

        // joe only as editor
        Story s3 = new Story(isPublic: true, title: "Story3", owner: bar)
        Editor e3 = new Editor(user: joe)
        s3.addToEditors(e3)

        // joe not related to story
        Story s4 = new Story(isPublic: true, title: "Story4", owner: foo)
        Editor e4 = new Editor(user: bar)
        s4.addToEditors(e4)

        [s1, s2, s3, s4]*.save()
    }

    void "test something"() {
        given:
        StoryController controller = new StoryController()

        when:
        def model = controller.index()

        then:
        model.result.size() == 3
        def stories = model.result.collect { it[0] }
        stories.size() == 3
        stories*.title == ['Story1', 'Story2', 'Story3']
    }
}

// Controller
class StoryController {

    def index() {
        def hql = "from Story as s left outer join s.editors as se \
                   where (s.owner.userName='joe' OR se.user.userName='joe')"
        def results = Story.executeQuery(hql)

        [result: results]
    }
}