My application works for everything except the call to display members of different boards. I can get the correct output in the db with an SQL query but having issues trying it in Grails using createCriteria.
Have to use Oracle 11g as my DB.
Grails 2.3.3
both the DB and Grails are local.
Here are my domains
class Trustee {
String salutation
String firstName
String middleName
String lastName
static hasMany = [board:Boards, membership:TrusteeMembership]
static constraints = {
salutation nullable: true
firstName nullable: true
middleName nullable: true
lastName nullable: true
}
//map to the existing DB table
static mapping = {
table 'BOT_TRUSTEE'
id column:'TRUSTEE_ID'
salutation column: 'SALUTATION'
firstName column: 'FIRST_NAME'
middleName column: 'MIDDLE_INITIAL'
lastName column: 'LAST_NAME'
version false
}
}
class Boards {
String boardName
static belongsTo = [trustee:Trustee, hospital:Hospitals]
static constraints = {
boardName nullable:true
}
static mapping = {
table name:"BOT_BOARD"
id column:'BOARD_ID'
trustee column:'TRUSTEE_ID'
hospital column:'HOSPITAL_ID'
boardName column:'BOARD'
version false
}
}
class Hospitals {
String hospitalName
static hasMany = [committees:Committees, board:Boards]
static constraints = {
hospitalName nullable:true
}
static mapping = {
table 'BOT_HOSPITAL'
id column:'HOSPITAL_ID'
hospitalName column:'HOSPITAL'
version false
}
}
class Committees {
String committeeName
String description
static belongsTo = [hospital: Hospitals]
static hasMany = [membership:TrusteeMembership]
static constraints = {
committeeName nullable:true
description nullable:true
}
static mapping = {
table 'BOT_COMMITTEE'
id column:'COMMITTEE_ID'
hospital column:'HOSPITAL_ID'
committeeName column:'COMMITTEE'
description column:'DESCRIPTION'
version false
}
}
class TrusteeMembership implements Serializable{
String position
String type
static belongsTo = [trustee:Trustee, committees:Committees]//
static constraints = {
position nullable:true
type nullable:true
}
static mapping = {
table 'BOT_TRUSTEE_COMMITTEES'
version false
id composite: ['trustee','committees']
trustee column:'TRUSTEE_ID'
committees column: 'COMMITTEE_ID'
position column:'POSITION'
type column:'TYPE'
}
Here is my controller
def members(){
def letter = params.letter
def commId = params.committee
params.max = Math.min(params.max ? params.int('max'): 15, 100)
def indexSearch = Trustee.createCriteria().list(params){
//search by First letter of lastName
if(letter != null){
ilike("lastName", "${letter}%")
}
//search by lastName
if(params.lastName){
ilike("lastName", "%${params.lastName}%")
}
//search by firstName
if(params.firstName){
ilike("firstName", "%${params.firstName}%")
}
//search by boardName
if(params.boardId){
//display only members within a board id
board{
eq("id", "%${params.boardId}%")
}
}
order("lastName", "asc")
}
respond Hospitals.list(params), model:[hospitalsInstanceCount: Hospitals.count(),
trusteeInstanceList : indexSearch]
}
//search by boardName
if(params.boardId){
//display only members with the boardName
board{
eq("id", params.long('boardId'))
}
}
I ended up with this for the correct result.
Related
I am developing one application in grails. I have following kind of mapping. Now I am saving object of DemoD class but its not saving values neither showing me any error while save. I have printed all created object and all looks fine. but still I am now able to save records.
class DemoS {
String firstName
String lastName
Long rollNumber
String address1
String address2
String city
String state
static constraints = {
address2 nullable:true
}
static hasMany = [demoAList: DemoA]
}
class DemoD {
Date date
static hasMany = [demoAList: DemoA]
def beforeInsert = {
date = new Date()
}
}
class DemoA {
Long id
Boolean absent
Boolean halfday
String notes
Date date
static belongsTo = [demoS:DemoS, demoD:DemoD]
static constraints = {
notes nullable: true
}
}
class UploadDataService {
def saveUploadedData(def dataList) {
def i = 0
DemoD ddObj = new DemoD()
//Getting this dataList from excel and now creating object for each row.
dataList?.each{ rowList ->
if(i != 0){
def dsObj = DemoS.get(rowList[0]?.longValue())
DemoA daObj = new DemoA([id:rowList[0]?.longValue(),absent:rowList[1],halfday:rowList[2],notes:rowList[3] ? rowList[3] : ''])
dsObj.addToDemoAList(daObj)
daObj.demoS = dsObj
ddObj.addToDemoAList(daObj)
daObj.demoD = ddObj
}
i++
}
ddObj.save(saveOnError: true)
}
}
Assuming you have three domain objs defined as such:
class Author {
String name
static hasMany = [books: Book]
}
class Book {
String name
static belongsTo = [author: Author]
static hasMany = [words: Word]
}
class Word {
String text
Set<Author> getAuthors() {
// This throws GenericJDBCException:
Author.where {
books.words == this
}
}
}
Why does getAuthors() fail with ERROR spi.SqlExceptionHelper - Parameter "#1" is not set; but works fine if rewritten using a Criteria:
public Set<Author> getAuthors() {
// This works as expected:
Author.withCriteria {
books {
words {
eq('id', this.id)
}
}
}
}
Do I have the syntax of the 'where query' wrong???
It seems like the criteria for your query is sort of misleading. books and words are both associations and you are expecting that words to be equal to single instance of the word object.
You can try this:
def getAuthors() {
Author.where {
books{
words {
id == this.id
}
}
}.list()
}
If I have four domain classes like this:
class Branch {
String name
static hasMany = [users:Users]
static mappedBy = [users:'branch']
static mapping = {
id column: 'f_branch_id'
name column: 'f_name'
}
}
class Users {
String name
static hasMany = [account:Account]
static mappedBy = [account:'user']
static belongsTo= [branch:Branch, title:Title]
static mapping = {
id column: 'f_user_id',
name column: 'f_name',
branch column: 'k_branch_id'
}
}
class Account {
String username
static belongsTo = [user:Users]
static mapping = {
id column: 'f_account_id'
user column: 'f_user_id'
username column: 'f_username'
}
}
class JoinTable implements Serializable {
Account account
Role role
static mapping = {
id composite : ['role', 'account']
role column :'k_role_id'
account column :'k_account_id'
version false
}
}
How can i get branch from JoinTable using criteria query
i try this process but fail for alias problem
def criteria = JoinTable.createCriteria()
def list = criteria.list {
account {
user{
branch{
eq("id", "2")
}
}
}
}
Domains
class Branch {
String name
static hasMany = [users:Users]
static mapping = {
id column: 'f_branch_id'
name column: 'f_name'
}
}
class Title {
...
}
class Users {
String name
static hasMany = [account:Account]
static belongsTo= [branch:Branch, title:Title]
static mapping = {...}
}
class Account {
String username
static belongsTo = [user:Users]
static mapping = {...}
}
class Role {
...
}
class JoinTable implements Serializable {
Account account
Role role
static mapping = {
id composite : ['role', 'account']
role column :'k_role_id'
account column :'k_account_id'
version false
}
}
Test
#TestMixin(GrailsUnitTestMixin)
#Mock([Act, Branch, Title, Users, Account, Role, JoinTable])
class EaseTests {
void testCriteria(){
10.times{
def b = new Branch().save(validate:false, flush:true)
10.times{
def u = new Users(branch:b).save(validate:false, flush:true)
10.times{
def a = new Account(user:u).save(validate:false, flush:true)
def joinTableRow = new JoinTable(account: a).save(validate:false, flush:true)
}
}
}
def c = JoinTable.createCriteria()
def results = c{
account{
user {
branch{
idEq(2l)
}
}
}
}
assert results
}
}
Have no idea why this happened, it worked two weeks ago. Here is the exception log:
No signature of method: xxxxx.UserInfo.findAllByEmail() is applicable for argument types: () values: []
Possible solutions: findAllByEmail([Ljava.lang.Object;). Stacktrace follows:
groovy.lang.MissingMethodException:
No signature of method: xxxxxx.UserInfo.findAllByEmail() is applicable for argument types: () values: []
Possible solutions: findAllByEmail([Ljava.lang.Object;)
at org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2.doCall(GormStaticApi.groovy:105)
at xxxxxx.FacebookController.checkEmail(FacebookController.groovy:87)
at xcompare.FacebookController$_closure2.doCall(FacebookController.groovy:49)
at xxxxxxx.OpenIDFilter.doFilter(OpenIDFilter.groovy:64)
at java.lang.Thread.run(Thread.java:662)
this is the code of FacebookController.groovy:
private boolean checkEmail(String email){
def users = UserInfo.findAllByEmail(email)
if(users){
// email is not available
return false;
}
return true;
}
and here is the code from UserInfo:
class UserInfo extends SecUser {
Provider provider
String activationCode
String firstName
String lastName
String email
Boolean active
UserType type
Date dateCreated
Date lastUpdated
Category category
static constraints = {
email unique:true, nullable:true, email:true
provider nullable:true
activationCode nullable:true
firstName blank:true, nullable:true
lastName blank:true, nullable:true
category nullable:true
}
String toString() {
// normal user
if(!openIds){
return username
}
// openid user
String name = "";
if(firstName){
name += firstName;
if(lastName){
name += " "+lastName;
}
}else{
name = email;
}
return name;
}
}
I'm not sure, but maybe it's because email is empty. So try:
private boolean checkEmail(String email){
if (!email) {
//TODO don't think that it's what you want
return true
}
int count = UserInfo.countByEmail(email)
return count == 0
}
While generating controller and view for a Domain class as:
class Book {
static constraints = {
bookId blank:false
bookTitle blank:false
}
private int bookId
private String bookTitle
private String author
private double price
private Date edition
private String publisher
}
Giving Error saying :
Can not set int field lms.Book.bookId to java.lang.Class
I think if u add 'private' to field declaration, u have to write getter and setter for this field:
class Book {
static constraints = {
bookId blank:false
bookTitle blank:false
}
private Integer bookId
...
Integer getBookId() { this.bookId }
void setBookId(Integer bookId) { this.bookId = bookId }
....
}
Change "int" to "Integer" (and "double" to "Double" too), e.g.
class Book {
static constraints = {
bookId blank:false
bookTitle blank:false
}
private Integer bookId
private String bookTitle
private String author
private Double price
private Date edition
private String publisher
}
Also, I doubt whether you can have a "blank" constraint on an Integer, change it to:
bookId nullable: false
assuming that is what you want (or remove it altogether, as the nullable: false constraint is implicit).