Grails mapping objects - grails

I am new to grails and still trying to wrap my head around the mapping of objects. In our project we have three classes that are causing some problems Attendee, Vendor, and Person An attendee has one person and a vendor has many persons so we went with the following setup:
class Person{
String firstName
//Other details...
}
class Attendee {
Person person
}
class Vendor{
static hasMany = [
person:person
]
}
So the objects are being hydrated via a web form and I can confirm that the person details are being hydrated from a log statement. However we get the following error:
Message ORA-01400: cannot insert NULL into ("EIGHT_STATES_USER"."ATTENDEE"."PERSON_ID")
so we added static belongsTo = [attendee: Attendee, vendor: Vendor] to our Person based on a stackoverflow we read. But then when we tried to save the Attendee it wanted to create a Vendor.
Not sure where to go from here.

Try adding a mapping to your Attendee object:
Person person
static mapping = {
person cascade: "all"
}
More information about the custom mapping can be found here: http://grails.org/doc/2.3.x/guide/GORM.html#customCascadeBehaviour

The way you currently have it defined, you need to save the Person object first and then add it to the Attendee and save. You don't need the belongsTo in Person.
class Person {
String firstName
//Other details...
}
class Attendee {
Person person
}
class Vendor {
static hasMany = [
people:Person
]
}
def person = new Person(params)
if (person.save(flush:true)) {
def attendee = new Attendee(params)
attendee.person = person
attendee.save(flush:true)
}

Related

How to maintain order in grails many-many relationship

My project requires me to maintain the insertion and retrieval order in a many-many relationship. By default, groovy saves the elements as a Set in many-many relationship. I want to do it in a List. I am not sure how to update the relationship to use List instead of Set. Any help would be appreciated.
class Course{
static belongsTo = Teacher
static hasMany = [teacher:Teacher]
static mapping = {
teacher joinTable : [name: TeacherCourse]
}
}
class Teacher{
static hasMany = [course:Course]
static mapping = {
course joinTable : [name: TeacherCourse]
}
}
save() call on either Teacher or Course also inserts a new row in TeacherCourse table. It works with no issues. In Database there the tables are:-
Teacher (PK: Id)
Course (PK: Id)
TeacherCourse(PK: [Teacher_id,Course_id])
Is there a way I can maintain the order of insertion and retrieval in many-many relationship?
Thank you..
Edit
In controller save()
def courseInstance = new Course()
List <Teacher> teacherList= []
teacherList.add(Teacher.findById(65))
teacherList.add(Teacher.findById(36))
courseInstance.courseUnits = teacherList
courseInstance.save(flush:true)
Try this:
class Course {
List teachers
static belongsTo = Teacher
static hasMany = [teachers:Teacher]
static mapping = {
teachers joinTable : [name: TeacherCourse]
}
}
class Teacher {
List courses
static hasMany = [courses:Course]
static mapping = {
courses joinTable : [name: TeacherCourse]
}
}
Reference

Groovy/Grails many-to-many delete relation

I have 2 domain class with a many to many relationship. When I delete the entity that belongs to the other, I have to remove the relation before in order to avoid a foreign key error. These relations are connected via the third class, third table in MySQL.
class City {
String nameCity
static hasMany = [visits:Visit]
/* FIRST VARIANT. REMOVES ONE VISIT ONLY */
def beforeDelete() {
Visit.withNewSession {
def visitList = Visit.findByCity(this)
visitList.each { it.delete(flush: true) }
}
}
}
//_____________________________________________
class Visit { // it is the relation class
City city
Person person
}
//_____________________________________________
class Person {
String namePerson
static hasMany = [visits:Visit]
}
So when I delete the relation between two classes, it removes one relation only. I mean, if we have 1 City and 1 Person, and try to delete this City, the app functions OK. But if you have more than one Person attached to the City, we will have:
"Cannot delete or update a parent row: a foreign key constraint fails". But one relation is deleted.
If I try to delete the City one more time, the second Person will be deleted. My app behaves like that until the last Person to be deleted. So, beforeDelete() method works great.
My problem is I don't understand how to create a collection of relations and remove them all in a cycle (loop). If I make like this:
class City {
String nameCity
static hasMany = [visits:Visit]
/* SECOND VARIANT. TYPE CAST EXCEPTION */
Collection<Visit> visitList() {
Visit.findByCity(this)
}
def beforeDelete() {
Visit.withNewSession {
visitList().each { it.delete(flush: true) }
}
}
}
I have org.codehaus.groovy.runtime.typehandling.GroovyCastException 'Cannot cast object 'mypackage.Visit : 1' with class 'mypackage.Visit' to class 'java.util.Collection'.
Any thoughts and help highly appreciated.
Have you tried the following? In theory should work...
class City {
String nameCity
static hasMany = [visits:Visit]
class Visit { // it is the relation class
City city
Person person
static belongsTo = [city:City, person:Person]
}
class Person {
String namePerson
static hasMany = [visits:Visit]
}
And just make a normal delete. In this way, if you delete a City or a Person, all its related visits will be deleted

How to implement Self-Referencing Relationships in Grails?

Given the following User class:
class User {
String name
static hasMany = [friends: User]
}
I want that a User can have many friends which are instances of the user domain class.
How do I have to implement the friend relationship of a user?
1. How Do you Define the relathionship
class User {
static hasMany = [ friends: User ]
static mappedBy = [ friends: 'friends' ] //this how you refer to it using GORM as well as Database
String name
String toString() {
name
}
def static constrains () {
name(nullable:false,required:true)
}
def static mapping={
/ / further database custom mappings ,like custom ID field/generation
}
}
2.How to save Data:
def init = {servletContext->
if(User?.list()==null) { // you need to import User class :)
def user = new User(name:"danielad")
def friends= new User(name:'confile')
def friends2=new User(name:'stackoverflow.com')
user.addToFriends(friends)
user.addToFriends(friends2)
user.save(flash:true)
}
}
3# . Your question is repeated on this stack overflow link :
Maintaining both sides of self-referential many-to-many relationship in Grails domain object
It looks like many-to-many relationship (one user has a lot of friends, and is a friend of a lot of users). So one of the solution will be to create new domain class, lets say it Frendship. And then modify User domain class like here:
class Friendship {
belongsTo = [
friend1: User
, friend2: User
]
}
class User{
String name
hasMany = [
hasFriends: Friendship
, isFriendOf: Friendship
]
static mappedBy = [
hasFriends: 'friend1'
, isFriendOf: 'frined2'
]
}

grails .removeFrom when object exists elsewhere in class

So essentially I have two classes:
Class User {
String Name
}
Class Project {
User requestedBy
static hasMany =
[
assignedTo: User
]
}
Now, I can set the requestedBy to say, User 1.
I can also do Project.addToAssignedTo(User 1).
The problem comes when I want to remove the user from assigned to when they already exist as the requestedBy. I can remove other users without problem:
Project.removeFromAssignedTo(User 1).save(failOnError: true, flush: true)
I get no errors of any kind, the data just simply does not get removed. Any help would be appreciated!
Thanks!
When defining multiple relationships to the same class, you should define the bidirectional relationship, and use the mappedBy property to define both sides of that relationship:
class User {
String Name
hasMany = [requestedProjects: Project, assignedProjects: Project]
}
class Project {
User requestedBy
static hasMany =
[
assignedTo: User
]
static mappedBy = [requestedBy: 'requestedProjects', assignedTo: 'assignedProjects']
}
Hopefully that solves your problem.

grails - how to save ArrayList in db

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]
}

Resources