In Grails I have these 4 domain classes:
package com.whatever.ts4
class A_class {
String aName
static hasMany = [b_class: B_class]
}
package com.whatever.ts4
class B_class {
String bName
A_class a_class
static hasMany = [c_class: C_class]
static belongsTo = [A_class]
}
package com.whatever.ts4
class C_class {
String cName
B_class b_class
static hasMany = [d_class: D_class]
static belongsTo = [B_class]
}
package com.whatever.ts4
class D_class {
Long rowNumber
String dataValue
C_class c_class
static belongsTo = [C_class]
}
Simple ER diagram:
A_class 1=>many B_class 1=>many C_class 1=>many D_class
I'm successfully populating them in BootStrap.groovy
Now,given an single A_class id, I need to obtain a set with these columns:
aName, bName, cName, rowNumber, dataValue
Can I do that using namedQueries?
I’ve tried putting this in the A_class domain class:
static namedQueries = {
myNamedQuery { aid ->
createAlias b_class,'b'
createAlias 'b.c_class','c'
createAlias 'c.d_class','d'
eq 'id',aid
}
}
I like the idea of a named query, because this result set will need to be returned for different A_class id’s. I can utilize a Service to prep the data and call it via the Controller which will render it as JSON (I digress). But, perhaps there is a Groovier way?
You don't need named query for this kind of action. You will obtain all information that you need just by taking it from A_class entity. For example:
def a_class_entity = A_class.get(id)
def b_names = a_class_entity.b_class.bName // set of all bNames
//<-- Not sure if flatten() works with spread collection fields, but it should -->
def c_names = a_class_entity.b_class.c_class.flatten().cName // collection of all cNames
def rowNumbers = a_class_entity.b_class.c_class.d_class.flatten().rowNumber // collection of all rowNumbers
def dataValues = a_class_entity.b_class.c_class.d_class.flatten().dataValue // collection of all dataValues
Related
I have a list of Clients and each client has one or more Venues.
These are two separate Domain classes where Venue has client id
I want to create a multiple value MAP which will have Client name as Key and Venue names as value
example :
def dataMap=["Client1":["Venue1","Venue2","Venue3"],"Client2":["Venue1","Venue2"]]
Domain Class:Client
class Client {
String name;
static hasMany = [venues: Venue];
}
Domain Class:Venue
class Venue {
String name;
String addressLine1;
String addressLine2;
String City
static belongsTo = [client: Client];
}
The same as aiolos wrote, with the standard Groovy method collectEntries():
def dataMap = Client.findAllWhere(/*yourCondition*/).collectEntries { client ->
[(client.name): client.venues.name]
}
What have you tried before and where do you stuck?
Here is one simple approach:
def dataMap = [:]
Client.findAllWhere(/*yourCondition*/).each { client ->
dataMap[client.name] = client.venues.name
}
I am trying to write a query in Grails to return a set of results from a domain class, but within those return the relevant results of a separate class whom have the parentId of the main class.
def query = Cars.where {
(colour == 'red')
}
And then within each list item include the set of parts relating to that CAR ID (as an example of what I'm trying to achieve, I know the code is incorrect though....
query.each{
this car. add(Parts.whereCarID{it.id})
}
If you define your domain model properly, you should get it without a criteria involved.
As far as I understand you need to add static hasMany = [parts: Parts] in your Cars domain class, and static belongsTo = [car:Cars] in your Parts class.
So for example, here how it might look:
class Cars {
string colour
static hasMany = [parts:Parts]
// ... rest of your properties
}
class Parts {
static belongsTo = [car:Cars]
// ... rest of your properties
}
And to get your result just do this:
def cars = Cars.findAllByColour('red')
Then you can do:
cars.each { car->
println car.parts // <-- all the parts for each car is here
}
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]
}
I am having problems persisting domain objects where I have a many-to-many relationship with a join table
class A{
String name
static hasMany = [bs:B]
}
class B{
String surname
static belongsTo=A
static hasMany=[as:A]
}
A a = new A(name:'Test')
B b = new B(surname:'user')
a.addToBs(b)
a.save(flush:true)
Then what I would expect to see is the following
Table A Table AB Table B
id name a_id b_id id surname
1 Test 1 1 1 User
However, the data only persists into table A.
Does anybody know what I am doing wrong ?
thanks
I have found this link which is shows a clear way of mapping many to many relationships
http://chrisbroadfoot.id.au/2008/07/19/many-to-many-relationship-mapping-with-gorm-grails
I still havent been able to get it working the way that I want to at the moment
I tried imitating your code and cascading works for me.
Class A:
package searcher
class A {
String name
static hasMany = [bs:B]
static constraints = {
}
public String toString() {
def s = "Name: $name\n Bs: "
bs.each {
s = "$s $it "
}
return s
}
}
Class B:
package searcher
class B {
String surname
static belongsTo = A
static hasMany = [as:A]
static constraints = {
}
}
Controller Source:
package searcher
class ManyController {
def ab = {
A a = new A(name:'Test')
B b = new B(surname:'user')
a.addToBs(b)
a.save(flush:true)
render A.list()
}
}
Produces output:
[Name: Test Bs: searcher.B : 1 ]
I didn't run into the problem you did, but I did have some initial trouble that was fixed by doing a grails clean. Have you tried a variety of database configurations? I was just using an in memory hsqldb set to create-drop. If you're using a DBMS that I happen to have installed I'll try pointing it to another database and giving it a whirl.