看似随机1 = 1,其中GORM的where子句在其中闭合 [英] Seemingly Random 1=1 where clause generated by GORM's where closure

查看:1521
本文介绍了看似随机1 = 1,其中GORM的where子句在其中闭合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有问题的示例程序:



解决方案



请参阅解决方案分支
https://github.com/HybridProgrammer/GormOneIsOneError/commit/8c3d77f82081d0367961345b4fc70c789e322318

列出队伍至列表<角色>



在GORM文档中,映射字段的声明经常被忽略,这也适用于此情况。



希望这也适用于您。


Sample Program With Problem: https://github.com/HybridProgrammer/GormOneIsOneError

Problematic GORM Code

def query = UserData.where {
        (
                teams { id in me.getAuthorities().id } && status { isOpen == true }
        ) || (
                owner == me && status { isOpen == true }
        )
    }

Summary of the Problem

The generated SQL query occasionally produces a where clause containing 1=1 when I would expect to see teams_alia1_.id in (?)

Detailed Description of the Problem

I wrote two integration test to illustrate this problem:

Please see src/intrgration-test/groovy/ExampleITSpec.groovy

Integration Test 1

void "never fails - direct approach"() {
    given:
    setupData()
    def me = User.first()

    when:
    def query = UserData.where {
        (
                teams { id in me.getAuthorities().id } && status { isOpen == true }
        ) || (
                owner == me && status { isOpen == true }
        )
    }

    then:
    me.getAuthorities().size() == 1
    query.size() == 2
}

Always generates SQL

select count(*) as y0_ 
from user_data this_ inner join status status_ali2_ 
     on this_.status_id=status_ali2_.id 
     inner join workflow_role_teams teams5_ 
     on this_.id=teams5_.user_data_teams_id 
     inner join role teams_alia1_ 
     on teams5_.role_id=teams_alia1_.id 
where 
(((teams_alia1_.id in (?)) and (status_ali2_.is_open=?)) 
or 
(this_.owner_id=? and (status_ali2_.is_open=?))) limit ?

Integration Test 2

void "sometimes fails"() {
    given:
    setupData()
    def me = User.first()

    when:
    def query = exampleService.getMyOrMyTeamsData(me)

    then:
    me.getAuthorities().size() == 1
    query.size() == 2
}

Occasionally generates SQL

select count(*) as y0_ 
from user_data this_ inner join status status_ali2_ 
    on this_.status_id=status_ali2_.id 
    inner join workflow_role_teams teams5_ 
    on this_.id=teams5_.user_data_teams_id 
    inner join role teams_alia1_ 
    on teams5_.role_id=teams_alia1_.id 
where 
((1=1 and (status_ali2_.is_open=?)) 
or 
(this_.owner_id=? and (status_ali2_.is_open=?))) limit ?

Where does the 1=1 come from?

ExampleService

def getMyOrMyTeamsData(User me) {
    // To fix the test Toggle these two lines
    def user = me
//        def user = User.get(me.id)

    def query = UserData.where {
        (
                teams { id in me.getAuthorities().id } && status { isOpen == true }
        ) || (
                owner == user && status { isOpen == true }
        )
    }

    return query

}

Update 1

While debugging the application you can clearly see authorities variable is passed along to DetachedCriteria#handleJunction(Closure callable) in the working version but vanishes when called from the service method.

Integration Test 1 - Has authorities attribute

Integration Test 2 - No authorities attribute

Solution

Please see solution branch https://github.com/HybridProgrammer/GormOneIsOneError/commit/8c3d77f82081d0367961345b4fc70c789e322318

解决方案

For me the test always fails and I don't know why test 2 and 3 show different behavior, but after I changed List teams to List<Role> teams in UserData.groovy, test 3 passed.

In the GORM docs the declaration of mapped fields is often omited, which also works in this case.

Hope this also works for you.

这篇关于看似随机1 = 1,其中GORM的where子句在其中闭合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆