GORM mappings in Grails
Posted By : Aakash Baweja | 02-Aug-2013
To understand the concept of mapping in grails we first have to take a look on understanding the concepts of GORM and Domain Modelling.
GORM:
GORM is Grails' object relational mapping (ORM) implementation. It uses Hibernate 3, the dynamic nature of Groovy with its static and dynamic typing along with the convention of Grails.
Domain Modelling in Grails
When building Grails applications you have to consider the problem domain you are trying to solve.
To create a domain class run the create-domain-class command as follows:
grails create-domain-class org.grocerystore.Grocery
The result will be a class at grails-app/domain/org/grocerystore/Grocery.groovy:
package org.bookstore class Grocery { }
This class will map automatically to a table in the database called grocery (the same name as the class).
Now define its properties as Java types. For example:
package org.grocerystore class Grocery { String name int price }
Each property is mapped to a column in the database.
Association in GORM
Relationships define how domain classes interact with each other. Unless specified explicitly at both ends, a relationship exists only in the direction it is defined.
We add both warriors to battle1 and battle1 to both warriors. We only need to save the warrior objects that are the owners of the relationships, and all associations are preserved.
-
1:1 Relationship
class Warrior { String name int numEnemyKilled Weapon weapon } class Weapon { String type String manufacturer }
In this case we have a unidirectional relationship from Warrior to Weapon.
When we rerun the Grails application, GORM will recreate a new Weapon table. It will also recognize the Weapon field of Warrior as an association with the Weapon class, and create a foreign key relationship between the warrior and weapon tables accordingly. Here, We are saying that a Warrior "has a" Weapon but a Weapon does not necessarily "have a" Warrior.
We can model bi-directional associations by simply adding a Warrior field to the Weapon. This will then be reflected in the relational model by GORM adding a warrior_id field to the weapon table.
class Weapon { String type String manufacturer Warrior warrior }
Now,to denote ownership in a relationship, GORM uses an optional static field applied to a domain class, called belongsTo.
class Weapon { String type String manufacturer Warrior warrior static belongsTo = Warrior }
-
1:n Relationship
A one-to-many relationship applies when an instance of class is associated with many instances of another class.To indicate the "has many" associations between Warrior and Weapon, we insert a static hasMany setting.
class Warrior { String name int numEnemyKilled Weapon weapon static hasMany = [ weapons: Weapon] } class Weapon { String type String manufacturer Warrior warrior static belongsTo = Warrior }
The hasMany setting is defined as a Map containing a key and class for each domain object that is associated. For each hasMany key encountered on a domain class, GORM will inject an addTo(key) method. This translates to an addToWeapons method which is added to Warrior.
Example:
Warrior.hasMany.each { def nameSuffix = it.key.substring(0,1).toUpperCase() def relation = "${nameSuffix}${it.key.substring(1)}" Warrior.metaClass."addTo${relation}" { "Add to ${relation}" } } def warrior = new Warrior() assert warrior.addToWeapons() == "Add to Weapons"
-
m:n Relationships
In GORM, all we need to do to make many to many relationships is to make the association bi-directional and give ownership to one side by applying a belongsTo setting. GORM will take care of the rest.
class Warrior { String name int numEnemyKilled static hasMany = [battles: Battle] static belongsTo = [Battle] } class Battle{ static hasMany = [ warriors: Warrior] }
A warrior may have fought in many battles and a battle may have many soldiers fighting each other.
When maintaining a database, it does not matter whether we add battles to warriors or warriors to battles, GORM will maintain both sides of the relationship.
def warrior1= new Warrior(); def warrior2= new Warrior(); def battle1 = new Battle(); def battle2 = new Battle(); warrior1.addToBattles(battle1) warrior2.addToBattles(battle1) battle1.addToWarriors(warrior1) battle1.addToWarriors(warrior2) warrior1.save() warrior12.save()
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Aakash Baweja