删除Grails服务中的记录

时间:2016-01-08 13:26:03

标签: grails

Grails服务中,我必须从Db中删除记录,但我得到以下错误:

spi.SqlExceptionHelper , Connection is read-only. Queries leading to data modification are not allowed

虽然我的服务中有@Transactional(readOnly = false),但这里是我的服务代码中的删除部分:

 def adsDurationIs7 =null
    adsDurationIs7= Ads.findAllByDuration("7 days",[sort: "dateCreated",    order: "asc"])
 adsDurationIs7.each {
            Ads.get(it.id).delete(flush: true)
}

2 个答案:

答案 0 :(得分:3)

我不确定为什么这不起作用,但即使它确实你做的工作也尽可能昂贵。您将所有实例加载到内存中(包括所有非延迟属性和集合),然后为每个实例加载id并使用该实例再次加载get调用实例(尽管如果你很幸运和/或你正确配置了缓存这个可能是无操作的),然后使用它一次删除一个数据库记录。而且您在数据库中订购,这会增加处理时间,但由于您要删除查询返回的所有内容,因此完全没有必要。

你真正想要的是最终运行类似于

的SQL的GORM代码
delete from ads where duration=?

PreparedStatement将?参数值设置为"7 days"

此“where”查询将完全执行以下操作:

Ads.where { duration == '7 days' }.deleteAll()

这个HQL更新也是如此:

Ads.executeUpdate 'delete Ads a where a.duration = :duration',
                  [duration: '7 days']

所以你的服务应该是

import grails.transaction.Transactional

@Transactional
class MyService {

   void deleteAdsDurationIs7() {
      Ads.where { duration == '7 days' }.deleteAll()
   }
}

import grails.transaction.Transactional

@Transactional
class MyService {

   void deleteAdsDurationIs7() {
      Ads.executeUpdate 'delete Ads a where a.duration = :duration',
                        [duration: '7 days']
   }
}

答案 1 :(得分:0)

您正在从控制器的功能执行此服务功能,这不是事务性的。将 @Transactional 添加到控制器的功能。

这是一个例子: https://stackoverflow.com/a/21998182/2166188