I'm using Grails 2.4.4. I've got domain class
class Purchase {
static hasMany = [dataList:DataByPeriod]
String name
Set<DataByPeriod> dataList
public Set<DataByPeriod> getDataList(){
dataList?.findAll { (!it.isDeleted) }
}
def getPeriodList(){
this.dataList?.period?.unique()?.sort{it.name}
}
}
and another two:
class DataByPeriod {
static belongsTo = [purchase:Purchase, period:Period]
Long value
}
class Period {
static hasMany = [dataList:DataByPeriod]
String name
}
Now I want to receive all periods for given purchaseInstance. If I do:
purchaseInstance?.dataList?.period?.unique()?.sort{it.name}
I'll get correct data (getter for dataList will be called and all records with isDeleted==true will be ignored
But if I I do:
purchaseInstance?.getPeriodList()
getter will not be called and all records will be shown?
Why does this happens? Why I even cannot change my 'getPeriodList()` method to:
def getPeriodList(){
this.getDataList()?.period?.unique()?.sort{it.name}
}
It says that 'there is no method getDataList() for class Purchase'.
Related
I have three classes in grails application
class Category {
String name
}
class Application {
String name
static hasMany =[specialCategoryies:SpecialCategory]
}
class SpecialCategory {
Category category
Integer points
static belongsTo =[application:Application]
}
Here while I am saving the applicationInstance I don't want save duplicate
specialCategories values like ..specialCategories does not have same
category value again ..
application.addToSpecialCategoryies(newSpecialCategory(category:Category.get(1),points:2))
application.addToSpecialCategoryies(newSpecialCategory(category:Category.get(1),points:3))
here i application instance should rise error that category value repeated..
so how define constraints for hasMany properties in domain class......?
suggest how to write constraints to avoid duplicate values of category
You might try using a custom validator in your Application constraints section. For example, one way to check for duplicate property values is to collect the values into an array and compare them to the corresponding unique array (with duplicated elements removed):
class Application {
String name
static hasMany =[specialCategoryies:SpecialCategory]
static constraints = {
specialCategoryies validator: { specialCategories, obj ->
def specialCategoriesIdArray = specialCategories.collect {it?.category?.getId()}
return (specialCategoriesIdArray.size() == specialCategoriesIdArray.unique().size())?true:'application.validator.specialcategoryduplicate.error'
}
}
}
When trying to save a special category with an existing category, it will throw a validation error when saving. You can test with the following:
def cat1 = new Category(name:"Cat 1").save(flush:true)
def cat2 = new Category(name:"Cat 2").save(flush:true)
def app = new Application()
app.name = "Test"
app.addToSpecialCategoryies(new SpecialCategory(category: Category.get(1), points:2))
app.addToSpecialCategoryies(new SpecialCategory(category: Category.get(2), points:2))
app.addToSpecialCategoryies(new SpecialCategory(category: Category.get(1), points:3))
if ( app.save(flush:true) ){
log.info "Saved!"
} else {
log.error "NOT Saved. Error:"
app.errors.each {
log.error it
}
}
I have a grails-plugin called "listadmin" there is a domain model "Liste":
package listadmin
class Liste {
String internal_name
String public_name
Boolean edtiable = true
Boolean visible = true
static hasMany = [eintrage : ListenEintrag]
static constraints = {
internal_name(unique : true , blank : false);
}
String toString() {
"${public_name}"
}
}
I have service called "SECO_ListenService" in the same module (grails-plugin):
package listadmin
class SECO_ListenService {
def getEntriesOfList(String intnalListName) {
def aList = Liste.findByInternal_name(intnalListName)
return aList
}
}
Now I try to call this service from an other module (grails-plugin) called "institutionadmin". The SECO_ListenService should return a list of strings for an select of a domain model in the inistitutionadmin:
package institutionadmin
import listadmin.SECO_ListenService
class Einrichtung {
Long einrichtungs_type
Long type_of_conzept
int anzahl_gruppen
int anzahl_kinder_pro_Gruppe
String offnungszeiten
static hasMany = [rooms : Raum]
static constraints = {
def aList = []
def sECO_ListenService = new SECO_ListenService()
aList=sECO_ListenService.getEntriesOfList("einrichtung_type")
einrichtungs_type(inList: aList)
}
}
If I try to run this application with the both modules. I get the following error:
Caused by MissingMethodException: No signature of method:
listadmin.Liste.methodMissing() is applicable for argument types: ()
values: []
It seemed to be that the service class don't know the "Liste"-domain-model. But I don't know where the error is. I also tried to call other standard methods like "findAll" but without any success.
Has anybody an idea where my mistake could be?
To get a service in a static context you need to access the grailsApplication spring bean. This can be done thought Holders. Example:
class MyService {
List<String> getAvailable() {
return ['A','B','C']
}
}
class MyDomainClass {
String something
static constraints = {
something inList: getSomethingList()
}
static List<String> getSomethingList() {
def myService = Holders.grailsApplication.mainContext.getBean('myService')
return myService.getAvailable()
}
}
I'm having trouble getting saves cascaded down my object hierarchy. Below is the code of my object hierarchy.
class Entity {
static hasMany = [attributes: Attribute]
}
class Attribute extends ValuePossessor {
static belongsTo = Entity
}
abstract class ValuePossessor {
def valueService
Value value
void setValue(val) {
this.value = valueService.Create(val)
this.value.possessor = this
}
}
abstract class Value {
static belongsTo = [possessor: ValuePossessor]
}
class StringValue extends Value {
String value
}
The valueService is simply a service with a big switch statement that creates the correct value type (string, boolean, int, etc.).
Entity e = new Entity()
Attribute attr = new Attribute()
attr.setValue(1)
e.addToAttributes(attr)
e.save()
The above code correctly creates all objects, but fails to save the value object. The entity and attribute are saved, but the value is not. Am I missing some identifier needed to cascade all the way down to the value object?
Figured this out. Apparently there is some magic in the grails dynamic setters. I changed the setValue(val) method to set(val) and it started working. Lesson learned: don't override grails' dynamically added methods because they are built with magic, pixy dust, and unicorn urine.
I'm a newbie in grails. i'm having a problem right now in my domain classes. I have 3 domain classes, class Patient,class Nurse and class NursePatient, the class NursePatient is a composite key where you can see who is the attending Nurse in a Patient, so if you view its table you can only see the id's of nurses and patients. This is my code for Nurse class:
class Nurse {
String name
Nurse partner
boolean idle = true
static belongsTo = [hospital: Hospital]
static constraints = {
name(blank:false)
partner(nullable:true)
hospital(nullable:false)
}
String toString(){
"Nurse ${name}"
}
}
--> and this is my domain class for NursePatient:
class NursePatient implements Serializable{
Nurse nurse
Patient patient
static mapping = {
version false
id composite:['nurse', 'patient']
}
static constraints = {
patient(nullable:false, validator:{val, obj -> val.hospital == obj.nurse.hospital})
nurse(nullable:false)
}
String toString(){
"Nurse ${nurse.name} - ${patient.name}"
}
void saveIt(Nurse x, Patient y){
def np = new NursePatient(nurse: x, patient: y)
if(np.save()){
def n = nurse.get(nurse.id)
n.idle = false
}
}
}
--> I was asked to print a list of nurses who doesn't have a patient. I was thinking that the moment I save in table using the saveIt() method from class NursePatient, once the save() is successful it changes the value of the property idle of class Nurse from true to false so that querying is much more easier. My problem is I don't if my code in class NursePatient is correct or is it possible to change the value of a property from another class. Please Help me.. thank You!!
Changing properties of domain classes inside different classes is fine.
However, you don't really need a NursePatient class. If you declare the relationship between Nurses and Patients as many-to-many, like this:
class Nurse {
static hasMany = [patients: Patient]
...
}
class Patient {
static hasMany = [nurses: Nurse]
...
}
then Grails will create and update the needed join table automatically. You can then query for all the nurses without patients using Criteria API:
def nursesWithoutPatients = Nurse.withCriteria { isEmpty("patients") }
I use grails-1.3.2 and hbase plugin.
I have some difficulty in creating one-to-Many association with
hbase (i can work with hibernate), so
i decided to try create one-to-Many association with using ArrayList.
Here are my domain classes and controllers:
class Contacts {
String con
static constraints = {}
}
class ContactsController {
def create = {
def contact = new Contacts()
contact.con = params.con
contact.save(flush:true)
}
}
class User {
String firstname
String lastname
// static hasMany = [contact: Contacts]
static ArrayList<Contacts> contact
static constraints = {}
}
class UserController{
def create = {
def user = new User()
user.properties = params
user.save(flush: true)
}
def addContact = {
def user = User.get(params.userID)
def contact = Contacts.get(params.contactID)
user.contact.add(contact)
user.save(flush:true)
}
}
In addContact action user.contact = null, so it can not work.
In user does nor appear contact field.
Can someone help me understand what i have to do for saving ArrayList in db?
I don't know anything about hbase, but the static contact property of the User class looks very suspicious. The fact that this property is static, implies that every user has the same contact list, which seems unlikely to be the desired behaviour.
In a standard GORM domain model - assuming you want each User to have their own contact list - this would be defined
class User {
String firstname
String lastname
static hasMany = [contact: Contacts]
}
Although it looks like we're also defining a static property here, it's actually just the definition of how the Contact and User classes are related (AKA mapping) that is static. The contact property that is dynamically added to the User class is non-static.
Aside
I recommend renaming the Contacts class to Contact and the contact property to contacts. The GORM mapping would then look like this:
class User {
String firstname
String lastname
static hasMany = [contacts: Contact]
}