简体   繁体   中英

GORM domain.delete(flush: true) not firing HibernateException nor other feedback?

Given:

Foo () {
  Bar bar

  static contraints = {
      bar (nullable: false)
  }
}

and a Service to manage Bar types, where a method deletes:

line 105: BarService {
line 106:     public BarCommand deleteBar(long Id) {    
line 107:         Bar b = Bar.get(Id)
line 108:         if (!b.delete(flush: true)) {
line 109:             //handle error here

If there is an existing Foo, "f" that already has a Bar of id 1 (for exmaple) associated with it, then line 108 should fail with some error explaining "b cannot be deleted, it is assigned to Foo id: 1" however, all that happens is line 108 returns false on truthiness and drops into the error handling regardless of whether delete was successful or not.

How do we know when we delete a domain whether the delete succeeded or failed? the doco does not describe this - Hibernate reports that a HibernateException should fire, but no exceptions are fired in any Unit test scenario...

( http://docs.grails.org/latest/ref/Domain%20Classes/delete.html )

I realize domain.delete() would not return anything as the delete is not communicated to the DB until a flush event, so I thought explicitly calling flush: true would address this, but it does not appear to.

Personally I dislike the inefficiency of retrieving an object from the DB for the sole purpose of deleting it, so instead of this:

Bar b = Bar.get(Id)
if (!b.delete(flush: true)) {
  // handle error here
}

I would use HQL to perform the delete because this avoids the need to retrieve it first (the load() method is an alternative solution).

Integer rowsDeleted = Bar.executeUpdate('delete Bar where id = ?', [Id])
if (!rowsDeleted) {
  // handle error here
}

A further benefit of this approach is that executeUpdate returns the number of rows updated/deleted, so you can check whether the operation was successful.

i have used with transaction commit changes in database and its working great read this link for more information. https://github.com/grails/grails-core/issues/10444

def delete(long id) {

    Document FSDocumentInstance = Document.get(id)
    Document.withTransaction {
        if (FSDocumentInstance == null) {
            return
        }
        File file = new File(FSDocumentInstance.filePath)
        File test = new File(FSDocumentInstance.fullPath)
        test.delete()
        file.delete()
        FSDocumentInstance.delete()
        flash.message = "File deleted"
    }
        redirect(action: 'index')
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM