These are my domain class
GameCategory.groovy
class GameCategory {
String categoryName
String icon
String toString(){
"${categoryName}"
}
static hasMany = [ list:GameList]
static constraints = {
}
Game.groovy
class Game {
String gameTitle
float gamePrice
String gameDescription
Date releaseDate
float rating
int numberOfRaters
int numberOfReviews
String toString(){
"${gameTitle}"
}
static hasMany = [list : GameList ]
static constraints = {
}
GameList.groovy
class GameList {
static belongsTo = [game : Game , category : GameCategory]
static constraints = {
}
My question is, how do I retrieve all instance of a game given a category as parameter I'm having trouble understanding the hasMany and belongsTo in grails
GameList.findAllByCategory(myCategory).collect{it.game}
You could make it more complicated by using createCriteria but then you have to join with an alias and the code will become more complicated.
I'm trying to figure out how to make a derived boolean field in my domain class. The boolean field is derived from comparison to the mapped owner's values. Is this possible in GORM? I've tried it quite a few different ways and I keep getting various SQL errors. My domain classes are below:
class Reading {
float readingValue
Date dateCreated
boolean alarmedState
static constraints = {
readingValue(nullable: false)
}
static belongsTo = [sensor : Sensor]
static mapping = {
autoTimestamp true
sort "dateCreated"
alarmedState formula: "(READING_VALUE < SENSOR.ALARM_IF_LESS) || (READING_VALUE > SENSOR.ALARM_IF_GREATER)"
}
}
class Sensor {
String description
String location
SensorType typeEnum
double alarmIfGreater
double alarmIfLess
static hasMany = [readings : Reading]
static constraints = {
alarmIfGreater(nullable: true)
alarmIfLess(nullable: true)
description(blank: false)
location(blank: false)
typeEnum(blank: false)
}
}
The transients property might do what you want. E.g.
class Reading {
float readingValue
Date dateCreated
static constraints = {
readingValue(nullable: false)
}
static belongsTo = [sensor : Sensor]
static transients = ['alarmedState']
static mapping = {
autoTimestamp true
sort "dateCreated"
//alarmedState formula: "(READING_VALUE < SENSOR.ALARM_IF_LESS) || (READING_VALUE > SENSOR.ALARM_IF_GREATER)"
}
Boolean getAlarmedState() {
( readingValue < sensor.alarmIfLess || readingValue > sensor.alarmIfGreater )
}
}
I've not tested this code but it might get you on the right track...
I am getting the following error when I tried to create a new Employee in static scaffold:
Error 500: Internal Server Error
URI
/file-tracker/employee/save Class
org.hibernate.StaleStateException Message
Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
Around line 38 of
grails-app/controllers/org/simpragma/EmployeeController.groovy
Around line 191 of PageFragmentCachingFilter.java
What is wrong ?
package org.xyz
class Employee {
String name;
String department;
String role;
String userId;
String pw;
static mapping = {
table 'employee'
version false
id name: 'userId'
id generator: 'native'
}
static hasMany = [toAllocations: Allocation, fromAllocations: Allocation]
static mappedBy = [toAllocations: 'toEmployee', fromAllocations: 'fromEmployee']
static constraints = {
department nullable : true
role nullable : true
}
}
package org.xyz
class Allocation {
static hasOne = [file:File, toEmployee:Employee, fromEmployee:Employee, remark:Remark]
static mappedBy = [toEmployee: 'toAllocations', fromEmployee: 'fromAllocations' ]
static constraints = {
remark nullable: true
}
}
package org.xyz
class File {
String fileNumber;
Date requestedDate;
String requestedBy;
String priority;
Double budget;
String requestedByDepartment;
String subject;
static mapping = {
id name: 'fileNumber'
version false
id generator: 'native'
}
static hasMany = [allocations: Allocation]
static constraints = {
fileNumber nullable : true
priority nullable : true
budget nullable : true
}
}
package org.xyz
class Remark {
String remark;
Date remarkDate;
static belongsTo = [allocation: Allocation];
static constraints = {
}
}
In my case, for test purposes I was trying to assign my own id to object. I can't do that if id should be generated during save.
Recently I have started refactoring my Grails application, everything looked good until I got 'object references an unsaved transient instance' errors. While debugging I have found that id for one of my domain object is always null for every instance. Even for instances loaded from database.
I have found that composite id (which I use in that class) is known to cause problems, but it worked fine few days ago, since then, I have done a lot changes to this class but none of them should cause this kind of problems... at least I couldn't find change that could cause it.
class QuestionPriority implements Serializable{
static int maxPriority = 6
static int minPriority = 1
int priority = maxPriority
Date lastTestDate
Date nextTestDate = new Date()
static belongsTo = [question:Question, subscription:Subscription]
static constraints = {
nextTestDate(nullable: true)
lastTestDate(nullable: true)
}
static mapping = {
id composite: ['subscription', 'question']
version false
}
static QuestionPriority create(Subscription sub, Question question, boolean flush = false) {
assert sub != null
assert question != null
assert sub.id != null
assert question.id != null
QuestionPriority qp = new QuestionPriority(subscription: sub, question: question)
sub.addToPriorities(qp)
question.addToPriorities(qp)
assert (qp.save(flush: flush, insert: true, failOnError: true))
return qp
}
boolean equals(other) {
if (!(other instanceof QuestionPriority)) {
return false
}
other.subscription?.id == subscription?.id &&
other.getQuestionToAsk?.id == question?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (subscription) builder.append(subscription.id)
if (question) builder.append(question.id)
builder.toHashCode()
}
void markAsCorrect() {
priorityDown()
calculateNextTestDate()
}
void markAsWrong() {
priorityUp()
calculateNextTestDate()
}
String getQuestionToAsk() {
return question.question
}
String getExpectedAnswer() {
return question.answer
}
Date calculateNextTestDate() {
DailyTestMode mode = subscription.testMode
if (!lastTestDate) {
nextTestDate = new Date(0, 0, 0)
} else {
nextTestDate = mode.calculateNextAskDate(this)
}
return nextTestDate
}
static void delete(User user, Question q) {
QuestionPriority qp = get(user.id, q)
if (qp) {
qp.delete()
}
}
static QuestionPriority get(Subscription sub, Question question) {
assert sub != null
assert question != null
assert sub.id != null
assert question.id != null
QuestionPriority qp = find 'from QuestionPriority where subscription.id=:subId and question.id=:questionId',
[subId: sub.id, questionId: question.id]
if (!qp) {
qp = create(sub, question)
}
return qp
}
private void priorityUp() {
priority = Math.min(priority + 1, maxPriority)
lastTestDate = new Date()
calculateNextTestDate()
}
private void priorityDown() {
priority = Math.max(priority - 1, minPriority)
lastTestDate = new Date()
calculateNextTestDate()
}
}
I would really appreciate any help
-----EDIT-------
Question domain oject:
class Question {
String question
String answer
boolean deleted
static transients = [ 'deleted']
static belongsTo = [studyList: StudyList]
static hasMany = [priorities: QuestionPriority]
static constraints = {
question(blank:false)
answer(blank:false)
}
static mapping = {
priorities(cascade: 'all-delete-orphan')
}
void setAnswer(String a){
answer = a.trim()
}
String toString(){
return "${question} = ${answer}"
}
}
Subscription domain object
class Subscription implements Serializable {
boolean active = true
Integer rating = null
Date subscriptionStartDate = new Date()
String dailyTestModeLiteral
static belongsTo = [user:User, studyList:StudyList]
static hasMany = [priorities:QuestionPriority]
static constraints = {
priorities(nullable: true)
rating(nullable: true)
subscriptionStartDate(nullable: true)
}
static mapping = {
priorities(cascade: 'all-delete-orphan')
}
void setDailyTestMode(DailyTestMode mode){
dailyTestModeLiteral = mode.getModeLiteral()
for(QuestionPriority priority:priorities){
priority.calculateNextTestDate()
}
}
DailyTestMode getTestMode(){
return DailyTestMode.getMode(dailyTestModeLiteral)
}
public static Subscription create(User user, StudyList list, String testModeLiteral = NormalDailyTestStrategy.literal, boolean flush = false){
Subscription subscription = get(user.id, list.id)
if(!subscription){
withTransaction {
subscription = new Subscription(user: user, studyList: list, dailyTestModeLiteral: testModeLiteral)
user.addToSubscriptions(subscription)
list.addToSubscriptions(subscription)
subscription.save(failOnError: true, flush: true)
}
subscription.studyList.questions.each {
QuestionPriority.create(subscription, it)
}
}
return subscription
}
int getScore(){
float prioritySum = 0
float priorityMax = 0
float priorityMin = 0
priorities.each {
prioritySum += it.priority
priorityMin += 1
priorityMax += QuestionPriority.maxPriority
}
return Math.round(100 * (prioritySum-priorityMax)/(priorityMin - priorityMax))
}
public static void delete(User user, StudyList list){
Subscription subscription = get(user.id, list.id)
if(subscription){
subscription.delete()
}
}
static Subscription get(long userId, long studyListId) {
find 'from Subscription where user.id=:userId and studyList.id=:studyListId',
[userId: userId, studyListId: studyListId]
}
boolean equals(other) {
if (!(other instanceof Subscription)) {
return false
}
other.user?.id == user?.id &&
other.studyList?.id == studyList?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (studyList) builder.append(studyList.id)
builder.toHashCode()
}
boolean checkIfMatches(QuestionPriority questionPriority, String questionAsked, String answerGiven) {
return(questionPriority.question.question==questionAsked &&
questionPriority.question.answer == answerGiven)
}
QuestionPriority checkIfMatchesAny(String questionAsked, String answerGiven) {
Question q = Question.withCriteria {
and {
eq('question', questionAsked)
eq('answer', answerGiven)
eq('studyList', studyList)
}
}
if(q){
List<QuestionPriority> qp = QuestionPriority.withCriteria {
and {
eq('question', q)
eq('subscription', this)
}
}
if(qp.size()>0){
return qp[0]
}else{
return null
}
}
}
}
A few hours of debuging later I still know only that executing save(flush: true, failOnError: true) on QuestionPriority object returns unsaved object (no validation errors, no exceptions... no helpful information).
Any idea where to look or how to search for cause of this problem would be helpful, because I'm 100% stuck on this...
After hours of searching, changing framework to newest version and fixing new problems resulting from version change, I fixed this problem. It looks like changing composite ID into normal ID + composite unique key solved the problem. I couldn't find other solution, even thou my code worked fine with composite id for first couple of months... (any part of code related to composite id was changed when it stopped working) and I'm almost sure that I tried removing composite ID earlier and it didn't help then...
I have the following entities Alert and Location in Grails. But I cant seem to add the location to the alert_location table. The error is missing method exception. Pls help.
class Alerts {
static hasMany = [locations:Locations,users:Users]
Date alertDateTime
String pest
String crop
static constraints = {
alertDateTime (blank:false)
pest (blank:false)
crop (blank:false)
}
class Locations {
static hasMany = [ farms:Farms, reports:Reports, reportMessages:ReportMessages]
String locationName
String locationXY
static constraints = {
locationName (blank:false)
locationXY (blank:false, unique:true)
}
}
In my code,
Locations loc = new Locations();
loc.locationName = 'a'
loc.locationXY = 'aa'
loc.save()
Alerts a = new Alerts()
Date d = new Date()
a.alertDateTime =d
a.crop ="o"
a.pest ="c"
//a.save()
println loc.locationName
loc.addToAlerts(a)
a.save()
Try a.addToLocations(loc) instead because you are using a.save(). Otherwise do loc.save()