Seemingly Random 1=1 where 子句由 GORM 的 where 闭包生成
Seemingly Random 1=1 where clause generated by GORM's where closure
有问题的示例程序:https://github.com/HybridProgrammer/GormOneIsOneError
有问题的 GORM 代码
def query = UserData.where {
(
teams { id in me.getAuthorities().id } && status { isOpen == true }
) || (
owner == me && status { isOpen == true }
)
}
问题总结
生成的 SQL 查询偶尔会生成包含 1=1 的 where 子句,而我希望在 (?)
中看到 teams_alia1_.id
问题的详细描述
我写了两个集成测试来说明这个问题:
请参阅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 - 具有 authorities 属性
集成测试 2 - 没有权限属性
解决方案
对我来说,测试总是失败,我不知道为什么测试 2 和 3 表现出不同的行为,但是在我将 List teams
更改为 List<Role> teams
之后 UserData.groovy,测试 3通过。
在 GORM 文档中,映射字段的声明经常被省略,这在这种情况下也有效。
希望这对你也有用。
有问题的示例程序:https://github.com/HybridProgrammer/GormOneIsOneError
有问题的 GORM 代码
def query = UserData.where {
(
teams { id in me.getAuthorities().id } && status { isOpen == true }
) || (
owner == me && status { isOpen == true }
)
}
问题总结
生成的 SQL 查询偶尔会生成包含 1=1 的 where 子句,而我希望在 (?)
中看到 teams_alia1_.id问题的详细描述
我写了两个集成测试来说明这个问题:
请参阅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 - 具有 authorities 属性
集成测试 2 - 没有权限属性
解决方案
对我来说,测试总是失败,我不知道为什么测试 2 和 3 表现出不同的行为,但是在我将 List teams
更改为 List<Role> teams
之后 UserData.groovy,测试 3通过。
在 GORM 文档中,映射字段的声明经常被省略,这在这种情况下也有效。
希望这对你也有用。