removeFrom* not working and with no errors

grails

Solution

See this thread: http://grails.1312388.n4.nabble.com/GORM-doesn-t-inject-hashCode-and-equals-td1370512.html

I would recommend using a base class for your domain objects like this:

abstract class BaseDomain {

    @Override
    boolean equals(o) {
        if(this.is(o)) return true
        if(o == null) return false
        // hibernate creates dynamic subclasses, so 
        // checking o.class == class would fail most of the time
        if(!o.getClass().isAssignableFrom(getClass()) && 
            !getClass().isAssignableFrom(o.getClass())) return false

        if(ident() != null) {
            ident() == o.ident()
        } else {
            false
        }
    }

    @Override
    int hashCode() {
        ident()?.hashCode() ?: 0
    }

}

That way, any two objects with the same non-null database id will be considered equal.

Problem

I have what I think is a simple problem but have been unable to solve... For some reason I have a controller that uses removeFrom*.save() which throws no errors but does not do anything. Running Grails 1.2 Linux/Ubuntu The following application is stripped down to reproduce the problem... I have two domain objects via create-domain-class - Job (which has many notes) - Note (which belongs to Job) I have 3 controllers via create-controller - JobController (running scaffold) - NoteController (running scaffold) - JSONNoteController JSONNoteController has one primary method deleteItem which aims to remove/delete a note. It does the following - some request validation - removes the note from the job - jobInstance.removeFromNotes(noteInstance).save() - deletes the note - noteInstance.delete() - return a status and remaining data set as a json response. When I run this request - I get no errors but it appears that jobInstance.removeFromNotes(noteInstance).save() does nothing and does not throw any exception etc. How can I track down why?? I've attached a sample application that adds some data via BootStrap.groovy. Just run it - you can view the data via the default scaffold views. If you run linux, from a command line you can run the following GET "http://localhost:8080/gespm/JSONNote/deleteItem?job.id=1&note.id=2" You can run it over and over again and nothing different happens. You could also paste the URL into your webbrowser if you're running windows. Please help - I'm stuck!!! Code is here link text Note Domain ``` package beachit class Note { Date dateCreated Date lastUpdated String note static belongsTo = Job static constraints = { } String toString() { return note } } ``` Job Domain ``` package beachit class Job { Date dateCreated Date lastUpdated Date createDate Date startDate Date completionDate List notes static hasMany = [notes : Note] static constraints = { } String toString() { return createDate.toString() + " " + startDate.toString(); } } ``` JSONNoteController ``` package beachit import grails.converters.* import java.text.* class JSONNoteController { def test = { render "foobar test" } def index = { redirect(action:listAll,params:params) } // the delete, save and update actions only accept POST requests //static allowedMethods = [delete:'POST', save:'POST', update:'POST'] def getListService = { def message def status def all = Note.list() return all } def getListByJobService(jobId) { def message def status def jobInstance = Job.get(jobId) def all if(jobInstance) { all = jobInstance.notes } else { log.debug("getListByJobService job not found for jobId " + jobId) } return all } def listAll = { def message def status def listView listView = getListService() message = "Done" status = 0 def response = ['message': message, 'status':status, 'list': listView] render response as JSON } def deleteItem = { def jobInstance def noteInstance def message def status def jobId = 0 def noteId = 0 def instance def listView def response try { jobId = Integer.parseInt(params.job?.id) } catch (NumberFormatException ex) { log.debug("deleteItem error in jobId " + params.job?.id) log.debug(ex.getMessage()) } if (jobId && jobId > 0 ) { jobInstance = Job.get(jobId) if(jobInstance) { if (jobInstance.notes) { try { noteId = Integer.parseInt(params.note?.id) } catch (NumberFormatException ex) { log.debug("deleteItem error in noteId " + params.note?.id) log.debug(ex.getMessage()) } log.debug("note id =" + params.note.id) if (noteId && noteId > 0 ) { noteInstance = Note.get(noteId) if (noteInstance) { try { jobInstance.removeFromNotes(noteInstance).save() noteInstance.delete() message = "note ${noteId} deleted" status = 0 } catch(org.springframework.dao.DataIntegrityViolationException e) { message = "Note ${noteId} could not be deleted - references to it exist" status = 1 } /* catch(Exception e) { message = "Some New Error!!!" status = 10 } */ } else { message = "Note not found with id ${noteId}" status = 2 } } else { message = "Couldn't recognise Note id : ${params.note?.id}" status = 3 } } else { message = "No Notes found for Job : ${jobId}" status = 4 } } else { message = "Job not found with id ${jobId}" status = 5 } listView = getListByJobService(jobId) } // if (jobId) else { message = "Couldn't recognise Job id : ${params.job?.id}" status = 6 } response = ['message': message, 'status':status, 'list' : listView] render response as JSON } // deleteNote } ```

Original source