miso
miso

Reputation: 135

how to reload an instance of a domain class from a database grails?

I have 4 objects (instances of domain classes) called taxi, placed in an object called moveRequest under a property allocatedTaxi.

The classes look like this:

class MoveRequest{

Taxi allocatedTaxi
Zone destinationZone
Integer destination
String microDestination
String targetType = ""
String targetName = ""
Zone currentTaxiZone
Taxi obstructingTaxi
Taxi boardedTaxi

String state = "pending"
Boolean requestedSpecific
Date dateCreated

static constraints = {
    currentTaxiZone(nullable: true)
    obstructingTaxi(nullable: true)
    boardedTaxi(nullable: true)
}

static mapping = {
    version false
}

}

class Taxi {

String name
Integer position
Double voltage
Boolean busy
Integer orderNumber

static belongsTo = [rail: Rail]

static mapping = {
    version false
}

static constraints = {
    name blank: false
}

}

Now, while iterating over moveRequests i update position properties of the taxi objects using an sql statement in a function like this:

def updateTaxiPosition(def taxiName, def millimeters){
    def config = grailsApplication.config
    def sql = Sql.newInstance(config.grails.databaseURL, config.grails.databaseUsername, config.grails.databasePassword, config.grails.databaseDriverClassName)

    sql.getConnection().setAutoCommit(true)
    sql.execute("UPDATE taxi SET position= ? WHERE name = ?", [millimeters, taxiName])
    sql.close()
}

Now, the other way to do this would be to use this line of code:

moveRequest.allocatedTaxi.position = millimeters

But, since i need to update it fast im using the direct sql, because it automatically updates taxi position. Now the problem arrises when i try to access the changed position. I can only access the old position, even though the position has changed in the database, and when i try to do this:

println("taxi position: " + moveRequest.allocatedTaxi.position)

i get the old value before updating the position property. Now i have tried to refresh the moveRequest instance like this:

def refreshMoveRequestInformation(def moveRequest){
    def config = grailsApplication.config
    def sql = Sql.newInstance(config.grails.databaseURL, config.grails.databaseUsername, config.grails.databasePassword, config.grails.databaseDriverClassName)

    sql.getConnection().setAutoCommit(true)
    def row = sql.rows("SELECT * FROM taxi WHERE id=?", [moveRequest.allocatedTaxi.id])
    println("row -> taxi name: " + row.name + ", taxi position: " + row.position)
    sql.close()

    def newPosition = null
    row.each{
        newPosition = it.position
    }
    moveRequest.allocatedTaxi.position = newPosition
}

and also like this:

def refreshMoveRequestInformation(def moveRequest){
    def taxi = Taxi.get(moveRequest.allocatedTaxi.id)
    println("1 - new taxi name: " + taxi.name + ", taxi position: " + taxi.position)
    taxi.refresh()
    println("2 - new taxi name: " + taxi.name + ", taxi position: " + taxi.position)

    println("move request -> taxi name: " + moveRequest.allocatedTaxi.name + ", taxi position: " + moveRequest.allocatedTaxi.position)

    return moveRequest
}

but none of it seems to work. I keep getting the old value, even though the row instance shows the new one. How can i update the moveRequest instance (by that i mean reload from database) it's allocatedTaxi property (or more precisely, the position property)??

Upvotes: 3

Views: 4248

Answers (1)

Joshua Moore
Joshua Moore

Reputation: 24776

Two things you can do.

First, calling .refresh() on your domain instance will ensure it's loaded from the SOR (system of record), your database in this case.

Second, you may want to remove this domain class from Hibernates second level cache.

class SomeClass {
  static mapping = {
    cache false
  }
}

Upvotes: 2

Related Questions