Grails Multiple data source: org.springframework.beans.factory.NoUniqueBeanDefinitionException - grails

I recently posted a question about multiple data sources. Things were going well until I hit this issue:
Controller
def doSomething() {
def user=userService.getCurrentUser()
}
Service
class UserService {
def getCurrentUser() {
def principal = springSecurityService.principal
String username = principal.username
return find(username)
}
def find(String user) {
return User.find{username==user}
}
}
This had been working previously on single DataSource but now with both enabled I see this on the browser:
Error 500: Internal Server Error URI /xxx/xxx Class
org.springframework.beans.factory.NoUniqueBeanDefinitionException
Message No qualifying bean of type
[org.springframework.transaction.PlatformTransactionManager] is
defined: expected single matching bean but found 3:
transactionManager,transactionManager_countrycity,$primaryTransactionManager

Okay this is now resolved.
I think I found the issue: under grails 3 with multiple data sources if you have this import :
import org.springframework.transaction.annotation.Transactional
You will run into the above problems:
If you how ever have :
import grails.transaction.Transactional
things will work as expected. I hadn;t paid attention and let ide choose wrong declaration

Related

Grails. Could not resolve view with name 'index' in servlet with name 'grailsDispatcherServlet'

I'm getting started with Grails (3.x) Framework but I got stuck with this error while trying to render domain content to a view:
Error 500: Internal Server Error
URI /hello/index
Class javax.servlet.ServletException
Message: Could not resolve view with name 'index' in servlet with name 'grailsDispatcherServlet'
HelloController.groovy:
package helloworld
class HelloController {
def index() {
def Person persona1 = new Person(firstName: "someone", lastName: "stuck", age: 21)
[persona:persona1]
}
}
Person.groovy:
package helloworld
class Person {
String firstName
String lastName
int age
}
Make sure that grails-app/views/hello/index.gsp file exists.
I know that this has an answer, but I thought I'd chime in that I am using Grails 3.0.11 and I found that somethings code like the following will work
render(view: 'index', model: [data: value])
Where as the following will fail with the error above.
def index() {
[data:value]
}
If I have time, I will poke around more with this and attempt to understand what's going on.
if you're using GNU/Linux, check the folder name, files, etc. for case inconsistency.
grails-app/views/Hello/index.gsp
grails-app/views/hello/index.gsp <-- Not the same
GNU/Linux is case sensitive.
grails generate-views - generates GSP views for the given domain class

Grails, how to get the request object

Grails has a request object which is defined here.
The problem is when I try to use it, I get:
No such property: request for class:xxx
Reading the first 100 hits googling this error only produced one suggestion:
import javax.servlet.http.HttpServletRequest
import org.springframework.web.context.request.ServletRequestAttributes
:
def my() {
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
}
However, this gives:
groovy.lang.MissingPropertyException: No such property: RequestContextHolder for class: net.ohds.ReportService
How does one get a handle on the request object in Grails?
How do you find out about this? So few people have asked this question, it must be documented somewhere, or in some example, but I can't find either.
In Grails 3.0, from a service get the request object using:
grails-app/services/com/example/MyService.groovy
import org.grails.web.util.WebUtils
...
def request = WebUtils.retrieveGrailsWebRequest().getCurrentRequest()
def ip = request.getRemoteAddr()
Documentation:
https://docs.grails.org/latest/api/org/grails/web/util/WebUtils.html#retrieveGrailsWebRequest()
Note:
The old codehaus package has been deprecated.
Try following code:
import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest
import org.codehaus.groovy.grails.web.util.WebUtils
...
GrailsWebRequest webUtils = WebUtils.retrieveGrailsWebRequest()
def request = webUtils.getCurrentRequest()
I expect that you probably got "groovy.lang.MissingPropertyException: No such property: RequestContextHolder for class: net.ohds.ReportService" because you didn't import the "org.springframework.web.context.request.RequestContextHolder" class in your ReportService.
The most common place to want access to the request object is in a controller. From a controller you simply refer to the request property and it will be there. See http://grails.org/doc/latest/ref/Controllers/request.html.
The answer to how to access the request object from somewhere else may depend on what the somewhere else is.
UPDATE
I don't know why you are having trouble passing the request from a controller to a service, but you can. I suspect you are invoking the method incorrectly, but something like this will work...
// grails-app/services/com/demo/HelperService.groovy
package com.demo
class HelperService {
// you don't have to statically type the
// argument here... but you can
def doSomethingWithRequest(javax.servlet.http.HttpServletRequest req) {
// do whatever you want to do with req here...
}
}
A controller...
// grails-app/controllers/com/demo/DemoController.groovy
package com.demo
class DemoController {
def helperService
def index() {
helperService.doSomethingWithRequest request
render 'Success'
}
}

grails 2.1.1 command object service injection for custom validator

Grails 2.1.1
I can't seem to get a command object to be injected with a service so that I can use custom validator. I've tried several things, including
Grails command object data binding and
what the 2.1.1 docs on custom validator suggest, I just can't figure this one out..
Relevant Code:
class RegistrationCommand {
String username
def registrationService
static constraints = {
username validator: { val, obj ->
obj.registrationService.isUsernameUnique(val) }
}
}
class RegistrationService {
def isUsernameUnique(username){
def user = new User(username:username)
user.validate()
if(user.errors.hasFieldErrors("username")){
return false
}else{
return true
}
}
Resolved.. Issue was due to plugin.
I'm using a plugin for client side jquery validation (jquery-validation-ui-1.4.2). The command object being created by the plugin's controller wasn't getting injected with the service. The issue was reported https://github.com/limcheekin/jquery-validation-ui/issues/17 . The fix does work but has not been pushed upstream yet.

Unable to create new domain object in Grails

Hi there i am still very new to grails and I have not been able to figure out why this is happening.
I have a domain class:
package scheduler
class Client {
String name
static constraints = {}
}
And a controller:
package scheduler
class AdminController {
def create() {
def client = new Client(name:"John")
println client
}
}
Currently I am always getting null for client. Originally the above was a little more complex on the domain class side but I systematically dumbed it down to see if it was a problem there. I still can not get the above working.
The output is always
scheduler.Client : null
Please let me know if I need to provide anymore information.
It's not null, that's just the default output of the toString method that Grails adds. It prints the class name and the id. Since you haven't saved the instance, the id is null. If the instance was null the output would have been null, not scheduler.Client : null
If you want to see the data in the instance, use the Groovy dump() method, e.g.
def client = new Client(name:"John")
println client.dump()
You could also add a toString method that includes the name attribute, e.g.
package scheduler
class Client {
String name
String toString() { name }
}

Grails Spring security core pre-logout

I'm using Grails Spring Security Core plugin and I need to perform a few actions when logout happens such as delete some class instances related to the user. I tried the following code:
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import grails.plugins.springsecurity.Secured
class LogoutController {
def index = {
def currentUser = currentUser()
currentUser.searchedResults.each{searched->
def searchInstance = Search.get(searched.searchId)
searchInstance.delete()
}
redirect uri: SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout'
}
private currentUser(){
return User.get(springSecurityService.principal.id)
}
}
However Grails is giving the error: No such property: User for class: LogoutController
My guess is that this is happening because when I installed Spring security core plugin, the LogoutController and LoginController were created in a different package called "default package". Is there any way to overcome this issue? Any help would be appreciated! Thanks
You simply need to import the User class. Something like:
import mypackage.User

Resources