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()
    
    

 

About Author

Author Image
Aakash Baweja

Request for Proposal

Name is required

Comment is required

Sending message..