Object-Relational Mapping
fields to store the primary key and a version number. The primary-key field is usually required by Hibernate or by a domain object’s clients. The version number is used for optimistic locking. The trouble with these fields, however, is that typically the application’s business logic does not require them. They must be added to every domain class solely to support persistence.
O/R MAPPING IN GORM
Grails relies heavily on Convention over Configuration when defining ORM. It automatically treats classes in the grails-app/domain directory as being persistent. GORM automatically persists the properties of each class. It defaults table and column names from the class and property names. GORM also adds primary-key and version-number properties to each class.
The following is an example domain class. The Customer class has a field called name. Also, because this field has default visibility, Groovy automatically defines the name property by defining getName() and setName() methods.
class Customer {
String name }
GORM automatically maps the Customer class to the customer table and maps the name property to the name column. GORM adds an id property to the class and maps it to a primary-key column called id. It also adds a version property and maps it to a version column. Unlike a traditional ORM framework, GORM requires very little configuration, provided that the database schema matches the defaults.
Another nice feature of GORM is that it will maintain creation and last updated times for domain model classes. You simply have to define lastUpdated and dateCreated properties on your classes, and GORM will automatically update them. In comparison, you must write code to do this when using vanilla Hibernate.
GORM also makes it easy to map relationships by using static properties to supply metadata in a similar fashion to annotations in other languages. For example,
the static property hasMany defines the one-to-many relationships for a domain class. The value of the hasMany property is a map. Each map entry defines a one-to-many relationship: its key is the name of the property that stores the collection, and its value is the class of the collection elements. For each one-to-many relationship GORM adds a property to store the collection of objects, as well as methods for maintaining the relationship.
The following is an example of how to map a one-to-many relationship between the Customer class and the Account class.
class Customer { static hasMany = [accounts : Account]
}
class Account { static belongs To = Customer Customer customer
}
The collection of accounts is stored in a property called accounts, which GORM adds to the Customer class at runtime. The relationship is mapped using a foreign key called customer_id in the account table. The belongs To property specifies that a Customer owns the account and it should be deleted if the customer is deleted.
GORM also dynamically defines a couple of methods for managing this relationship. The add ToAccounts() method adds an account to the collection, and the removeFromAccounts() method removes an account. These methods also maintain the inverse relationship from Account to Customer. By automatically defining these methods, which would otherwise have to be written by hand, GORM simplifies the code and makes it less error prone.
CONFIGURING THE MAPPING
CoC reduces the amount of configuration that is required. Sometimes, however, you need to specify some aspects of the ORM. For example, table or column names might not match the defaults, or perhaps a class has derived properties that should not be persisted. To support these requirements, GORM lets you specify various aspects of the ORM. Rather than using a different configuration language such as XML or annotations, however, GORM uses snippets of Groovy code in the domain classes.
Here is an example of how to override the default table and column names and specify that a property should not be persisted.
References:
Archives