suman j
suman j

Reputation: 6980

Method on class [] was used outside of a Grails application controller

Having below grails config: Datasource.

environments {
development {
    dataSource {
        dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
        url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
    }

    datasource_staging_oracle {
        dbCreate = "none"
        url = "jdbc:oracle:thin:@//myoraclehost:1521/DBNAME"
        driverClassName = "oracle.jdbc.OracleDriver"
        username = "username"
        password = "password"
    }
}

Domain class:

import org.springframework.integration.Message

class SpringMessage {

    static mapping = {
        datasource 'staging_oracle'
        message type: 'blob', column: 'message_bytes'
        createdDate type: Date, column: 'created_date'
    }
    static constraints = {
    }

    String messageId
    Message<?> message
    Date createdDate
}

Inside the controller, fetching the records using:

SpringMessage springMessage = SpringMessage.findByMessageId('messsage_id_value')

Above line fails with below error: Method on class [com.foo.bar.SpringMessage] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.

How to resolve this? Googling shows grails "test" related posts. But this is not test code. Above findBy method is called from a grails controller. I am on grails 2.3.3 and unfortunately can not upgrade to latest grails as of now.

UPDATE
Controller code:

class FooController {
    def index() {
        foo2()
    }
    private def foo2() {
        SpringMessage springMessage = SpringMessage.findByMessageId('my_message_id') //This line blowsup
        if ( springMessage) {
            println springMessage.createdDate
        } else {
            println "not found"
        }
    }
}

I access the controller using http://localhost:8080/myapp/foo/index
UPDATE
Blob column declaration is incorrect in my original question. Correct version is below:

class SpringMessage {

    static mapping = {
        datasource 'staging_oracle'
        message type: 'blob', column: 'message_bytes'
        createdDate type: Date, column: 'created_date'
    }
    static constraints = {
    }

    String messageId
    Blob message
    Date createdDate
}

Upvotes: 2

Views: 9343

Answers (3)

saw303
saw303

Reputation: 9082

Your domain class SpringMessage uses a org.springframework.integration.Message as domain property message. There error tries to indicate that org.springframework.integration.Message is not a Grails domain object and cannot no be mapped against the database.

You need to introduce a domain object holding the relevant data of your org.springframework.integration.Message instance. Probably you are trying to store the payload of the Spring Integration Message.

class SpringMessage {

  static mapping = {
    datasource 'staging_oracle'
    message type: 'blob', column: 'message_bytes'
    createdDate type: Date, column: 'created_date'
  }
  static constraints = {
  }

  String messageId
  String message // use a String instead of the message instance
  Date createdDate
}

and then set the payload to the SpringMessage

new SpringMessage(
    messageId: 'ID', 
    message: message.payload, 
    createdDate: new Date()
).save()

Hope this helps.

Upvotes: 1

Daniel Black
Daniel Black

Reputation: 605

I just ran into this issue.

In my DataSource.groovy I was specifying the secondary dataSource as dataSource_mysql and in my domain class mapping block I had it the same. Turns out within the domain class I needed to reference the datasource as just mysql without the dataSource_.

Once I made this change I was able to call the domain methods from my controller without this error being thrown.

Upvotes: 2

suman j
suman j

Reputation: 6980

Issue is because of a typo in DataSource.groovy: dataSource word should have 'S' in upper case. Yikes. Grails should have warned on this.

environments {
  development {
    dataSource {
        dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
        url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
    }

    dataSource_staging_oracle {
        dbCreate = "none"
        url = "jdbc:oracle:thin:@//myoraclehost:1521/DBNAME"
        driverClassName = "oracle.jdbc.OracleDriver"
        username = "username"
        password = "password"
    }
}

Upvotes: 4

Related Questions