How do I define a relationship like the following:
A person can belong to many projects. A person can be the technical contact for a project or, they can be the business contact for a project or they can be both. If the person gets deleted the project doesn't get deleted. If a project gets deleted the person doesn't get deleted.
class Project {
String name
Person technicalContact
Person businessContact
static constraints = {
}
}
class Person {
String firstName
String lastName
String email
String phone
String department
static constraints = {
}
}
You can have 2 one-to-many in one table like this
class Project {
String name
}
class Person {
String firstName
String lastName
String email
String phone
String department
static hasMany = [technicalContactForProjects: Project ,
businessContactForProjects: Project
]
}
Grails will automatically make 2 relation table from that 2 hasMany, so you can delete its relation without delete the actual person or project.
Related
I have 4 Grails domain classes ( Domain1, Domain2, Domain3, Domain4). These domain objects map to legacy tables with exactly same set of columns. To be more precise, all of these tables have personFirstName, personLastName and personPhoneNumber columns.
The only thing different between these 4 domain classes is the table name they refer to.
Instead of copy/pasting same piece of code in four different places and just modifying this:
static mapping = {
table name:"legacy_table_name_A" <====== (only difference)
firstName column: "personFirstName"
lastName column: "personLastName"
phoneNumber column:"personPhoneNumber"
}
I was wondering if there is a way to do this all in one abstract class called MyAbstractDomainClass and have my Domain1, Domain2... extend it like this:
class MyAbstractDomainClass {
String firstName
String lastName
String phoneNumber
static mapping = {
firstName column: "personFirstName"
lastName column: "personLastName"
phoneNumber column:"personPhoneNumber"
}
}
class Domain1 extends MyAbstractDomainClass {
static mapping = {
}
}
How do I implement the static mapping for each Domain classes to have a different table name?
I am using Grails 2.4.2
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)
}
Hi I am just trying out grails and trying to learn more on domain class. I have two simple domain classes:
Domain Class 1
package grailtest
class Person {
String firstName
String lastName
int age
String email
static constraints = {
}
}
Domain Class 2
package grailtest
class Customer {
String customerId
Person personInCharge
static constraints = {
}
}
When I do a run-app, I can only see
grailtest.Person : 1
as the Person. How can I default it to a particular value, for instance firstName + lastName, to make the application more user friendly?
in the domain override toString method to what you wanted to be display. restart the app
You can use #ToString in case you want an elaborative way of logging or printing in standard out.
import groovy.transform.ToString
#ToString(includeNames=true, includeFields=true)
class Person {
String firstName
String lastName
int age
String email
}
For example,
def person = new Person(firstName: 'Test', lastName: 'hola',
age: 10, email: 'abc#xyz.com')
would give
Person(firstName:Test, lastName:hola, age:10, email:abc#xyz.com)
Find the view where it displays grailstest.Person: 1 and update it to:
${personInstance.firstName} ${personInstance.lastName}
By default this view should be in "views/person"
You put this code in the view .gsp
${personInstance?.firstname} ${personInstance?.lastname}
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
Have been trying to look for an answer for hours, but have so far not managed to come up with an adequate solution, so I'm hoping someone here might have some more experience with Grails, and implementing custom relationships in it.
My problem is that I have two classes:
Company
OrderConfig
OrderConfig contains two references to Company. 1 for a consignee, 1 for a shipper. I implemented the relationship (see below), and everything looks dandy, with my order_config table containing both a consignee_company_id column and a shipper_company_id column.
However, I do not want or need a company_id column at all. I would prefer using the CompanyName as the identifying column. How can I prevent Grails from automatically adding the id column to the company table, and instead use the companyName column as the primary key, thus ensuring my order_config table will be generated containing the companyName and not the company_id?
I tried embedding the company in the orderconfig class, and wrestled with all kinds of other options including the mappings, however I ran into trouble with each and every one of them.
Thanks in advance!
My code so far:
class OrderConfig {
static hasMany = [consignee:Company, shipper:Company]
String toString() {
return "${consignee}"
}
static constraints = {
consignee (blank:false, maxSize:10)
shipper (blank:false, maxSize:10)
}
Company consignee
Company shipper
}
class Company {
String toString() {
return "${companyName}"
}
static constraints = {
companyName(blank:false, maxSize:10)
companyAddress1(blank:false, maxSize:40)
companyAddress2(blank:false, maxSize:40)
companyAddress3(blank:false, maxSize:40)
companyAddress4(blank:false, maxSize:40)
companyZipCode(blank:false, maxSize:36)
companyCountry(blank:false, maxSize:36)
}
String companyName
String companyAddress1
String companyAddress2
String companyAddress3
String companyAddress4
String companyZipCode
String companyCountry
}
You need to look at the advanced GORM config options in the documentation, in section 5.5.2.1
There is an example
class Person {
String firstName
static hasMany = [addresses:Address]
static mapping = {
table 'people'
firstName column:'First_Name'
addresses joinTable:[name:'Person_Addresses', key:'Person_Id', column:'Address_Id']
}
}
there you can see how they are specifying the key and column name on which to do the stuff.
Edit -- I reread your question: if you are asking how to change it so Company has an assigned id, you might be able to do something like this example
static mapping = {
id generator:'assigned', column:'column_name',name:'propertyName'
}
where more options are available here: http://www.grails.org/doc/1.3.x/ref/Database%20Mapping/id.html