Grails pull object from has many - grails

I am trying to pull all the PostOrder's out where a child instance is present
My domain is as follows:
class PostOrder {
String pOrder
Date dateCreated
Picture picture
Post posts
Video video
static hasMany = [children : Child]
}
and the method i am trying to use to get the objects is:
def getAllInOrder(Child child){
def json = PostOrder.findAllByChildren(child, sort: 'dateCreated', order: 'desc') as JSON
return json
}
I am just getting sql exceptions from this.
Any Ideas?
also these are my exceptions:
util.JDBCExceptionReporter No value specified for parameter 1
errors.GrailsExceptionResolver SQLException occurred when processing request: [GET] /FYP/profile/appPosts - parameters:
child: 1
No value specified for parameter 1. Stacktrace follows:
java.sql.SQLException: No value specified for parameter 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.PreparedStatement.checkAllParametersSet(PreparedStatement.java:2595)
at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2571)
at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2497)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2251)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2.doCall(GormStaticApi.groovy:105)
at com.fyp.timeline.ProfileController$$ENmIB8q0.getAllInOrder(ProfileController.groovy:636)
at com.fyp.timeline.ProfileController$$ENmIB8q0.appPosts(ProfileController.groovy:624)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)

Try
PostOrder.findAllByChildren(child, [sort: 'dateCreated', order: 'desc'])
Although I don't think this will fix your problem entirely because in this instance, child is expected to be a list. Try this:
PostOrder.all.findAll{it.children.contains(child)}
It seems like there should be a better way to do that, maybe someone else can ring in.

Related

Hibernate: force get() to respect the data type of its parameter

Setup: Grails 2.5.6 with Hibernate 4.3.10
I have a table with a string id. Thing is, its values are numeric strings, and this seems to mess up get() when I pass in a value such as "000000".
Domain class:
class Term
{
static mapping = {
id name: 'code', generator: 'assigned'
version false
code column: 'CODE'
description column: 'DESC'
}
String code
String description
}
Data looks like:
CODE || DESC
-------++---------------------------
000000 || The Beginning of Time
201715 || Post Secondary Winter 2017
201815 || Post Secondary Winter 2018
999999 || The End of Time
And then in testing I found the following:
assert Term.list() // works fine
assert !Term.get('foo') // works fine
//assert Term.get('000000') // throws exception
The exception thrown is:
Method threw 'org.springframework.orm.hibernate4.HibernateSystemException' exception.
Provided id of the wrong type for class Term. Expected: class java.lang.String, got class java.lang.Long
org.hibernate.TypeMismatchException: Provided id of the wrong type for class Term. Expected: class java.lang.String, got class java.lang.Long
So it looks like at some point the '000000' and the '201715' and whatever else are being inconveniently converted into Long objects. Using as String doesn't help either. Can anyone help me tell Hibernate that this String should be treated as a String?
This seems like a Grails bug and I'm guessing it is because you have not declared id to be of type String in your domain class because it is mapped to a different field (which makes sense).
You could try adding
String id
to your domain class although that may not caused desired behaviour with column generation.
I would suggest rather than using get() you could use findByCode() as you have mapped your id to the code field and the result should be the same.

Throwing null pointer exception when accessing property of the domain object

Inside a controller i just test these two lines. RaceRegistration domain has a property compositeEvent. So, i access the Registration domain first and then access the compositeevent using .compositeEvent.
println (RaceRegistration.get(r.toLong()))
println (RaceRegistration.get(r.toLong())).compositeEvent
The following error is thrown. As you can see the first print succeeds i.e it gets the Registration domain but the second println fails. My question is why is it throwing null pointer when we are certain that the RaceRegistration domain was accessed successfully.
com.runnercard.registration.RaceRegistration : 8
ERROR errors.GrailsExceptionResolver: NullPointerException occurred when processing request: [POST] /roadrace/message/sendEmail - parameters:
I appreciate any help. Thanks!
Null is null. Don't doubt this: it is true.
The 'void' println expression evaluates to null and the failing code is roughly equivalent to the following:
x = println (RaceRegistration.get(r.toLong()))
// x is null - so the following results in a NullPointerException
x.compositeEvent
It is probable that the parenthesis is merely in the wrong spot (or even over-specified):
println (RaceRegistration.get(r.toLong()).compositeEvent)
// -or
println RaceRegistration.get(r.toLong()).compositeEvent

Save List of numbers in domain model error?

I am currently trying to save a List of numbers associated to a domain model in Grails and I keep getting errors. So the scenario is:
I have a Client Domain Model that is shown below and this has a HasMany relationship with a PhoneNumbers Domain model that is also shown below. There is a view where a bunch of numbers are added and then these are stored in a String [] for processing on the controller.
Client Domain:
class Client {
String name
List numbers = new ArrayList()
//This represents a message belonging to a single department
static hasMany = [numbers:PhoneNumbers]
static constraints = {
name(blank:false)
}
}
Phone Numbers Domain:
class PhoneNumbers {
String number
//This represents a message belonging to a single department
static belongsTo = [client:Client]
static constraints = {
number(blank:false)
}
}
As you can see the Client hasMany Phone Numbers and the Phone Numbers belongTo a Client. So in my controller I presumed all's I would need to do is to pass these numbers to the Domain in an Array or List and it would handle the cascade save, my controller function is below:
//This is an array of phone numbers stored in a sesson object as String []
def numbers = session.getAttribute("phoneNumbers")
def numbersConvert = numbers as List
def client = new Client(numbers: numbersConvert, name: params.name)
if (!client.save()) {
client.errors.each{
println(it)
}
}
so the controller above I would expect to take the array of numbers which I have confirmed has values and then convert that to a List. Then save the new Client data and cascade save all the numbers that that client has in the List. However this does not work and I get the error below:
GRAILS-7799: Subtype 'java.lang.String' of reloadable type com.tool.PhoneNumbers is not reloadable: may not see changes reloaded in this hierarchy (please comment on that jira)
| Error 2013-07-30 07:56:50,831 [http-bio-8080-exec-4] ERROR property.BasicPropertyAccessor - IllegalArgumentException in class: com.smstool.PhoneNumbers, getter method of property: id
| Error 2013-07-30 07:56:50,836 [http-bio-8080-exec-4] ERROR errors.GrailsExceptionResolver - IllegalArgumentException occurred when processing
object is not an instance of declaring class. Stacktrace follows:
Message: object is not an instance of declaring class
I did also try another approach to the save the data within the controller as shown below however this did not work either:
numbers.each{
def phoneNumber = new PhoneNumber(number: it).save(flush: true)
client.addToPhoneNumber(phoneNumber).save(flush: true)
}
I presume I am missing something silly and this is probably a really easy thing to do just so tired and need a little help.
Thanks in advance

Grails : Problems with Lazy List

I have a web page that allows the user to enter data which will form a Master / Detail relationship when stored to my database. I submit the data to a Grails controller that binds the data in to a Command Object. As I do not know how many "detail" rows will be submitted, I am attempting to use a Lazy List to bind the detail data to. I am failing spectacularly.
My command object looks like :
String title
List testItems = LazyList.decorate(new ArrayList(),
FactoryUtils.instantiateFactory(VocabQuestion.class));
When I submit the form I get the following exception :
| Error 2013-06-04 22:42:54,068 [http-bio-8080-exec-4] ERROR errors.GrailsExceptionResolver - MissingMethodException occurred when processing request: [POST] /*****/vocabulary/save - parameters:
testItems[1].question: Q2
title: Test
testItems[0].answer: A1
testItems[0].question: Q1
testItems[0].vocabulary_test_id:
testItems[1].answer: A2
create: Create
No signature of method: vocabularytest.TestCreationCommand.propertyMissing() is applicable for argument types: () values: []
Possible solutions: propertyMissing(java.lang.String). Stacktrace follows:
Message: No signature of method: vocabularytest.TestCreationCommand.propertyMissing() is applicable for argument types: () values: []
Possible solutions: propertyMissing(java.lang.String)
Line | Method
->> 102 | <init> in vocabularytest.TestCreationCommand
This exception happens very early on in the objects lifecycle, presumeably as Grails tries to bind the data to it.
If I define my Command Object as :
String title
List testItems = [new VocabQuestion()]
and only submit 1 detail record from the form, then everything works as expected.
Where am I going wrong?
EDIT
My VocabQuestion domain class is
package vocabularytest
class VocabQuestion {
static constraints = {
}
static belongsTo = [vocabularyTest: VocabularyTest]
String question
String answer
}
I found an answer ( might not be THE answer but it works )
I used the LazyList syntax that is native in later Groovy versions as follows.
List testItems = [].withLazyDefault {new VocabQuestion()}

Grails: Accessing GORM from a background thread

I have been struggling with this error for a week now, and I am seriously losing my mind over this! I have tried multible implementations and work-arounds and hacks and what not, but I just keep stubling into just another exception.
I am using the Executor plugin to run a method asynchroniously:
runAsync{
run(...)
}
The method initially deletes some objects:
page.delete(flush:true)
And then later possibly recreating those objects:
def page = new Page(type : Page.TYPE_TABLE, domain : domainVersion.domain, identifier : tableName)
page.save(flush: true, failOnError: true)
But that fails with the following exception:
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.ramboll.egs.ohs.domain.Domain#1]
The relationship between the Page and Domain is simply implemented by Page having a Domain attribute. No hasMany og belongsTo - as I was discouraged from this in an earlier post due to performance issues.
I think I have tried all thinkable combinations of save, merge, withTransachtion and PersistenceContextInterceptor...
How is this supposed to work? Examples please.
Thanks in advance!
It doesn't appear that working in a new thread is the issue, it looks like a standard validation problem. It's saying that the Page is null, which indicates a validation error since save() returns the instance if it was successful, or null if there's a one or more validation errors. There are a few options:
def page = new Page(type : Page.TYPE_TABLE,
domain: dbUpdate.domainVersion.domain, identifier: tableName)
page.save(flush:true)
if (page.hasErrors()) {
// handle errors
}
else {
def pageVersion = createPageVersion(page, dbUpdate.domainVersion,
con, tableName, dbUpdate.author).save(flush:true)
}
or use failOnError to throw an exception:
def page = new Page(type : Page.TYPE_TABLE, identifier: tableName,
domain: dbUpdate.domainVersion.domain).save(flush:true, failOnError: true)
def pageVersion = createPageVersion(page, dbUpdate.domainVersion,
con, tableName, dbUpdate.author).save(flush:true)

Resources