【问题标题】:Seemingly Random 1=1 where clause generated by GORM's where closureGORM 的 where 闭包生成的看似 Random 1=1 where 子句
【发布时间】:2017-04-10 19:36:02
【问题描述】:

有问题的示例程序:https://github.com/HybridProgrammer/GormOneIsOneError

有问题的 GORM 代码

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

问题总结

当我希望在 (?) 中看到 team_alia1_.id 时,生成的 SQL 查询偶尔会生成包含 1=1 的 where 子句

问题的详细描述

我写了两个集成测试来说明这个问题:

请参阅 src/intrgration-test/groovy/ExampleITSpec.groovy

​​>

集成测试 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
}

始终生成 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 ?

集成测试 2

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

    when:
    def query = exampleService.getMyOrMyTeamsData(me)

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

偶尔会生成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 ?

1=1 从何而来?

示例服务

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

}

更新 1

在调试应用程序时,您可以清楚地看到 authorities 变量在工作版本中传递给 DetachedCriteria#handleJunction(Closure callable),但在从服务方法调用时消失。

集成测试 1 - 具有权限属性

集成测试 2 - 无权限属性

解决方案

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

【问题讨论】:

  • 什么版本的grails?
  • Grails 版本:3.2.6
  • 当你使用静态类型而不是def时会发生什么?
  • 看起来很有希望。在我的 IDE (IntelliJ) 中运行时,所有测试都通过了。但是从命令行运行:grails test-app -integration -Dgrails.env=test test 在 ExampleITSpec.groovy 的第 99 行每次都会失败。我将更新版本推送到静态类型分支。我的更改:github.com/HybridProgrammer/GormOneIsOneError/commit/…
  • 在 IntelliJ 中再次运行,今天早上“有时失败”的测试再次失败。

标签: hibernate grails grails-orm


【解决方案1】:

对我来说,测试总是失败,我不知道为什么测试 2 和 3 显示不同的行为,但是在我将 UserData.groovy 中的 List teams 更改为 List<Role> teams 后,测试 3 通过了。

在 GORM 文档中,映射字段的声明通常被省略,这在这种情况下也有效。

希望这也对你有用。

【讨论】:

  • 我必须运行 grails clean 一次。所有的测试都通过了。非常感谢!
猜你喜欢
  • 2020-02-05
  • 2011-10-22
  • 2023-03-06
  • 2017-12-28
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
相关资源
最近更新 更多