Reputation: 6980
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
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
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
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