text:
def book = Book.findByTitle("Groovy in Action")book .addToAuthors(name:"Dierk Koenig") .addToAuthors(name:"Guillaume LaForge") .save()
5.1 Quick Start GuideA domain class can be created with the create-domain-class command:
This will create a class at the location
grails create-domain-class Person
grails-app/domain/Person.groovy such as the one below:
class Person { }
If you have the You can customize the class by adding properties:
dbCreate property set to "update", "create" or "create-drop" on your DataSource, Grails will automatically generated/modify the database tables for you.
Once you have a domain class try and manipulate it via the shell or console by typing:
class Person { String name Integer age Date lastVisit }
This loads an interactive GUI where you can type Groovy commands.
grails console
5.1.1 Basic CRUDTry performing some basic CRUD (Create/Read/Update/Delete) operations.
CreateTo create a domain class use the Groovy new operator, set its properties and call save:
The save method will persist your class to the database using the underlying Hibernate ORM layer.
def p = new Person(name:"Fred", age:40, lastVisit:new Date()) p.save()
ReadGrails transparently adds an implicit
id property to your domain class which you can use for retrieval:
This uses the get method that expects a database identifier to read the
def p = Person.get(1) assert 1 == p.id
Person object back from the db.
You can also load an object in a read-only state by using the read method:
In this case the underlying Hibernate engine will not do any dirty checking and the object will not be persisted. Note that if you explicitly call the save method then the object is placed back into a read-write state.In addition, you can also load an proxy for an instance by using the load method:
def p = Person.read(1)
This incurs no database access until a method other than getId() is called. Hibernate then initializes the proxied instance, or throws an exception if no record is found for the specified id.
def p = Person.load(1)
UpdateTo update an instance, set some properties and then simply call save again:
def p = Person.get(1)
p.name = "Bob"
DeleteTo delete an instance use the delete method:
def p = Person.get(1) p.delete()
5.2 Domain Modelling in GORMWhen building Grails applications you have to consider the problem domain you are trying to solve. For example if you were building an Amazon bookstore you would be thinking about books, authors, customers and publishers to name a few.These are modeled in GORM as Groovy classes so a
Book class may have a title, a release date, an ISBN number and so on. The next few sections show how to model the domain in GORM.To create a domain class you can run the create-domain-class target as follows:
The result will be a class at
grails create-domain-class Book
class Book { }
If you wish to use packages you can move the Book.groovy class into a sub directory under the domain directory and add the appropriate The above class will map automatically to a table in the database called
package declaration as per Groovy (and Java's) packaging rules.
book (the same name as the class). This behaviour is customizable through the ORM Domain Specific LanguageNow that you have a domain class you can define its properties as Java types. For example:
Each property is mapped to a column in the database, where the convention for column names is all lower case separated by underscores. For example
class Book { String title Date releaseDate String ISBN }
releaseDate maps onto a column
release_date. The SQL types are auto-detected from the Java types, but can be customized via Constraints or the ORM DSL.
5.2.1 Association in GORMRelationships define how domain classes interact with each other. Unless specified explicitly at both ends, a relationship exists only in the direction it is defined.
126.96.36.199 Many-to-one and one-to-oneA many-to-one relationship is the simplest kind, and is defined trivially using a property of the type of another domain class. Consider this example:
Example A
In this case we have a unidirectional many-to-one relationship from
class Face { Nose nose } class Nose { }
Face to
Nose. To make this relationship bidirectional define the other side as follows:
Example B
In this case we use the
class Face {
Nose nose
class Nose {
static belongsTo = [face:Face]
belongsTo setting to say that
Nose "belongs to"
Face. The result of this is that we can create a
Face, attach a
Nose instance to it and when we save or delete the
Face instance, GORM will save or delete the
Nose. In other words, saves and deletes will cascade from
Face to the associated
The example above will save both face and nose. Note that the inverse is not true and will result in an error due to a transient
new Face(nose:new Nose()).save()
Now if we delete the
new Nose(face:new Face()).save() // will cause an error
Face instance, the
Nose will go to:
To make the relationship a true one-to-one, use the
def f = Face.get(1) f.delete() // both Face and Nose deleted
hasOne property on the owning side, e.g.
Example C
Note that using this property puts the foreign key on the inverse table to the previous example, so in this case the foreign key column is stored in the
class Face {
static hasOne = [nose:Nose]
class Nose {
Face face
nose table inside a column called
face_id. Also,
hasOne only works with bidirectional relationships.Finally, it's a good idea to add a unique constraint on one side of the one-to-one relationship:
class Face { static hasOne = [nose:Nose] static constraints = { nose unique: true } }class Nose { Face face }
126.96.36.199 One-to-manyA one-to-many relationship is when one class, example
Author, has many instances of a another class, example
Book. With Grails you define such a relationship with the
hasMany setting:
In this case we have a unidirectional one-to-many. Grails will, by default, map this kind of relationship with a join table.
class Author { static hasMany = [ books : Book ] String name } class Book { String title }
The ORM DSL allows mapping unidirectional relationships using a foreign key association insteadGrails will automatically inject a property of type
java.util.Set into the domain class based on the
hasMany setting. This can be used to iterate over the collection:
def a = Author.get(1)a.books.each { println it.title }
The default fetch strategy used by Grails is "lazy", which means that the collection will be lazily initialized. This can lead to the n+1 problem if you are not careful.If you need "eager" fetching you can use the ORM DSL or specify eager fetching as part of a queryThe default cascading behaviour is to cascade saves and updates, but not deletes unless a
belongsTo is also specified:
If you have two properties of the same type on the many side of a one-to-many you have to use
class Author { static hasMany = [ books : Book ] String name } class Book { static belongsTo = [author:Author] String title }
mappedBy to specify which the collection is mapped:
This is also true if you have multiple collections that map to different properties on the many side:
class Airport { static hasMany = [flights:Flight] static mappedBy = [flights:"departureAirport"] } class Flight { Airport departureAirport Airport destinationAirport }
class Airport { static hasMany = [outboundFlights:Flight, inboundFlights:Flight] static mappedBy = [outboundFlights:"departureAirport", inboundFlights:"destinationAirport"] } class Flight { Airport departureAirport Airport destinationAirport }
184.108.40.206 Many-to-manyGrails supports many-to-many relationships by defining a
hasMany on both sides of the relationship and having a
belongsTo on the owned side of the relationship:
Grails maps a many-to-many using a join table at the database level. The owning side of the relationship, in this case
class Book { static belongsTo = Author static hasMany = [authors:Author] String title } class Author { static hasMany = [books:Book] String name }
Author, takes responsibility for persisting the relationship and is the only side that can cascade saves across.For example this will work and cascade saves:
However the below will only save the
new Author(name:"Stephen King") .addToBooks(new Book(title:"The Stand")) .addToBooks(new Book(title:"The Shining")) .save()
Book and not the authors!
This is the expected behaviour as, just like Hibernate, only one side of a many-to-many can take responsibility for managing the relationship.
new Book(name:"Groovy in Action") .addToAuthors(new Author(name:"Dierk Koenig")) .addToAuthors(new Author(name:"Guillaume Laforge")) .save()
Grails' Scaffolding feature does not currently support many-to-many relationship and hence you must write the code to manage the relationship yourself
184.108.40.206 Basic Collection TypesAs well as associations between different domain classes, GORM also supports mapping of basic collection types. For example, the following class creates a
nicknames association that is a
Set of
String instances:
GORM will map an association like the above using a join table. You can alter various aspects of how the join table is mapped using the
class Person { static hasMany = [nicknames:String] }
joinTable argument:
The example above will map to a table that looks like the following:bunch_o_nicknames Table
class Person { static hasMany = [nicknames:String] static mapping = { hasMany joinTable: [name: 'bunch_o_nicknames', key: 'person_id', column: 'nickname', type: "text"] } }
--------------------------------------------- | person_id | nickname | --------------------------------------------- | 1 | Fred | ---------------------------------------------
5.2.2 Composition in GORMAs well as association, Grails supports the notion of composition. In this case instead of mapping classes onto separate tables a class can be "embedded" within the current table. For example:
The resulting mapping would looking like this:
class Person { Address homeAddress Address workAddress static embedded = ['homeAddress', 'workAddress'] } class Address { String number String code }
If you define the
Addressclass in a separate Groovy file in the
grails-app/domaindirectory you will also get an
addresstable. If you don't want this to happen use Groovy's ability to define multiple classes per file and include the
Addressclass below the
Personclass in the
5.2.3 Inheritance in GORMGORM supports inheritance both from abstract base classes and concrete persistent GORM entities. For example:
In the above example we have a parent
class Content { String author } class BlogEntry extends Content { URL url } class Book extends Content { String ISBN } class PodCast extends Content { byte[] audioStream }
Content class and then various child classes with more specific behaviour.
ConsiderationsAt the database level Grails by default uses table-per-hierarchy mapping with a discriminator column called
class so the parent class (
Content) and its sub classes (
Book etc.), share the same table.Table-per-hierarchy mapping has a down side in that you cannot have non-nullable properties with inheritance mapping. An alternative is to use table-per-subclass which can be enabled via the ORM DSLHowever, excessive use of inheritance and table-per-subclass can result in poor query performance due to the excessive use of join queries. In general our advice is if you're going to use inheritance, don't abuse it and don't make your inheritance hierarchy too deep.
Polymorphic QueriesThe upshot of inheritance is that you get the ability to polymorphically query. For example using the list method on the
Content super class will return all sub classes of
def content = Content.list() // list all blog entries, books and pod casts content = Content.findAllByAuthor('Joe Bloggs') // find all by authordef podCasts = PodCast.list() // list only pod casts
5.2.4 Sets, Lists and Maps
Sets of objectsBy default when you define a relationship with GORM it is a
java.util.Set which is an unordered collection that cannot contain duplicates. In other words when you have:
The books property that GORM injects is a
class Author {
static hasMany = [books:Book]
java.util.Set. The problem with this is there is no ordering when accessing the collection, which may not be what you want. To get custom ordering you can say that the set is a
In this case a
class Author {
SortedSet books
static hasMany = [books:Book]
java.util.SortedSet implementation is used which means you have to implement
java.lang.Comparable in your Book class:
The result of the above class is that the Book instances in the books collections of the Author class will be ordered by their release date.
class Book implements Comparable { String title Date releaseDate = new Date() int compareTo(obj) { releaseDate.compareTo(obj.releaseDate) } }
Lists of objectsIf you simply want to be able to keep objects in the order which they were added and to be able to reference them by index like an array you can define your collection type as a
In this case when you add new elements to the books collection the order is retained in a sequential list indexed from 0 so you can do:
class Author {
List books
static hasMany = [books:Book]
The way this works at the database level is Hibernate creates a
author.books[0] // get the first book
books_idx column where it saves the index of the elements in the collection in order to retain this order at the db level.When using a
List, elements must be added to the collection before being saved, otherwise Hibernate will throw an exception (
org.hibernate.HibernateException: null index column for collection):
// This won't work! def book = new Book(title: 'The Shining') book.save() author.addToBooks(book)// Do it this way instead. def book = new Book(title: 'Misery') author.addToBooks(book) author.save()
Maps of ObjectsIf you want a simple map of string/value pairs GORM can map this with the following:
In this case the key and value of the map MUST be strings.If you want a Map of objects then you can do this:
class Author { Map books // map of ISBN:book names }def a = new Author() a.books = ["1590597583":"Grails Book"] a.save()
The static
class Book { Map authors static hasMany = [authors:Author] }def a = new Author(name:"Stephen King")def book = new Book() book.authors = [stephen:a] book.save()
hasMany property defines the type of the elements within the Map. The keys for the map must be strings.
A Note on Collection Types and PerformanceThe Java
Set type is a collection that doesn't allow duplicates. In order to ensure uniqueness when adding an entry to a
Set association Hibernate has to load the entire associations from the database. If you have a large numbers of entries in the association this can be costly in terms of performance.The same behavior is required for
List types, since Hibernate needs to load the entire association in-order to maintain order. Therefore it is recommended that if you anticipate a large numbers of records in the association that you make the association bidirectional so that the link can be created on the inverse side. For example consider the following code:
In this example the association link is being created by the child (Book) and hence it is not necessary to manipulate the collection directly resulting in fewer queries and more efficient code. Given an
def book = new Book(title:"New Grails Book") def author = Author.get(1) book.author = author book.save()
Author with a large number of associated
Book instances if you were to write code like the following you would see an impact on performance:
def book = new Book(title:"New Grails Book") def author = Author.get(1) author.addToBooks(book) author.save()
5.3 Persistence BasicsA key thing to remember about Grails is that under the surface Grails is using Hibernate for persistence. If you are coming from a background of using ActiveRecord or iBatis Hibernate's "session" model may feel a little strange.Essentially, Grails automatically binds a Hibernate session to the currently executing request. This allows you to use the save and delete methods as well as other GORM methods transparently.
5.3.1 Saving and UpdatingAn example of using the save method can be seen below:
A major difference with Hibernate is when you call save it does not necessarily perform any SQL operations at that point. Hibernate typically batches up SQL statements and executes them at the end. This is typically done for you automatically by Grails, which manages your Hibernate session.There are occasions, however, when you may want to control when those statements are executed or, in Hibernate terminology, when the session is "flushed". To do so you can use the flush argument to the save method:
def p = Person.get(1) p.save()
Note that in this case all pending SQL statements including previous saves will be synchronized with the db. This also allows you to catch any exceptions thrown, which is typically useful in highly concurrent scenarios involving optimistic locking:
def p = Person.get(1)
You can find out more about the subtleties of saving data in this article - a must read!
def p = Person.get(1) try { p.save(flush:true) } catch(Exception e) { // deal with exception }
5.3.2 Deleting ObjectsAn example of the delete method can be seen below:
By default Grails will use transactional write behind to perform the delete, if you want to perform the delete in place then you can use the
def p = Person.get(1) p.delete()
flush argument:
Using the
def p = Person.get(1)
flush argument will also allow you to catch any errors that may potentially occur during a delete. A common error that may occur is if you violate a database constraint, although this is normally down to a programming or schema error. The following example shows how to catch a
DataIntegrityViolationException that is thrown when you violate the database constraints:
Note that Grails does not supply a
def p = Person.get(1)try { p.delete(flush:true) } catch(org.springframework.dao.DataIntegrityViolationException e) { flash.message = "Could not delete person ${p.name}" redirect(action:"show", id:p.id) }
deleteAll method as deleting data is discouraged and can often be avoided through boolean flags/logic.If you really need to batch delete data you can use the executeUpdate method to do batch DML statements:
Customer.executeUpdate("delete Customer c where c.name = :oldName", [oldName:"Fred"])
5.3.3 Understanding Cascading Updates and DeletesIt is critical that you understand how cascading updates and deletes work when using GORM. The key part to remember is the
belongsTo setting which controls which class "owns" a relationship.Whether it is a one-to-one, one-to-many or many-to-many, defining
belongsTo will result in updates cascading from the owning class to its dependant (the other side of the relationship), and for many-/one-to-one and one-to-many relationships deletes will also cascade.If you do not define
belongsTo then no cascades will happen and you will have to manually save each object (except in the case of the one-to-many, in which case saves will cascade automatically if a new instance is in a
hasMany collection).Here is an example:
If I now create an
class Airport { String name static hasMany = [flights:Flight] }class Flight { String number static belongsTo = [airport:Airport] }
Airport and add some
Flights to it I can save the
Airport and have the updates cascaded down to each flight, hence saving the whole object graph:
Conversely if I later delete the
new Airport(name:"Gatwick") .addToFlights(new Flight(number:"BA3430")) .addToFlights(new Flight(number:"EZ0938")) .save()
Airport all
Flights associated with it will also be deleted:
However, if I were to remove
def airport = Airport.findByName("Gatwick")
belongsTo then the above cascading deletion code would not work. To understand this better take a look at the summaries below that describe the default behaviour of GORM with regards to specific associations. Also read part 2 of the GORM Gotchas series of articles to get a deeper understanding of relationships and cascading.
Bidirectional one-to-many with belongsTo
In the case of a bidirectional one-to-many where the many side defines a
class A { static hasMany = [bees:B] } class B { static belongsTo = [a:A] }
belongsTo then the cascade strategy is set to "ALL" for the one side and "NONE" for the many side.
Unidirectional one-to-many
In the case of a unidirectional one-to-many where the many side defines no belongsTo then the cascade strategy is set to "SAVE-UPDATE".
class A { static hasMany = [bees:B] }
class B { }
Bidirectional one-to-many, no belongsTo
In the case of a bidirectional one-to-many where the many side does not define a
class A { static hasMany = [bees:B] }
class B { A a }
belongsTo then the cascade strategy is set to "SAVE-UPDATE" for the one side and "NONE" for the many side.
Unidirectional one-to-one with belongsTo
In the case of a unidirectional one-to-one association that defines a
class A { }
class B { static belongsTo = [a:A] }
belongsTo then the cascade strategy is set to "ALL" for the owning side of the relationship (A->B) and "NONE" from the side that defines the
belongsTo (B->A)Note that if you need further control over cascading behaviour, you can use the ORM DSL.
5.3.4 Eager and Lazy FetchingAssociations in GORM are by default lazy. This is best explained by example:
Given the above domain classes and the following code:
class Airport { String name static hasMany = [flights:Flight] } class Flight { String number Location destination static belongsTo = [airport:Airport] } class Location { String city String country }
GORM will execute a single SQL query to fetch the
def airport = Airport.findByName("Gatwick")
airport.flights.each {
println it.destination.city
Airport instance, another to get its flights, and then 1 extra query for each iteration over the
flights association to get the current flight's destination. In other words you get N+1 queries (if you exclude the original one to get the airport).
Configuring Eager FetchingAn alternative approach that avoids the N+1 queries is to use eager fetching, which can be specified as follows:
In this case the
class Airport { String name static hasMany = [flights:Flight] static mapping = { flights lazy: false } }
flights association will be loaded at the same time as its
Airport instance, although a second query will be executed to fetch the collection. You can also use
fetch: 'join' instead of
lazy: false , in which case GORM will only execute a single query to get the airports and their flights. This works well for single-ended associations, but you need to be careful with one-to-manys. Queries will work as you'd expect right up to the moment you add a limit to the number of results you want. At that point, you will likely end up with fewer results than you were expecting. The reason for this is quite technical but ultimately the problem arises from GORM using a left outer join.So, the recommendation is currently to use
fetch: 'join' for single-ended associations and
lazy: false for one-to-manys.Be careful how and where you use eager loading because you could load your entire database into memory with too many eager associations. You can find more information on the mapping options in the section on the ORM DSL.
Using Batch FetchingAlthough eager fetching is appropriate for some cases, it is not always desirable. If you made everything eager you could quite possibly load your entire database into memory resulting in performance and memory problems. An alternative to eager fetching is to use batch fetching. Essentially, you can configure Hibernate to lazily fetch results in "batches". For example:
In this case, due to the
class Airport { String name static hasMany = [flights:Flight] static mapping = { flights batchSize:10 } }
batchSize argument, when you iterate over the
flights association, Hibernate will fetch results in batches of 10. For example if you had an
Airport that had 30 flights, if you didn't configure batch fetching you would get 1 query to fetch the
Airport and then
30 queries to fetch each flight. With batch fetching you get 1 query to fetch the
Airport and 3 queries to fetch each
Flight in batches of 10. In other words, batch fetching is an optimization of the lazy fetching strategy. Batch fetching can also be configured at the class level as follows:
Check out part 3 of the GORM Gotchas series for more in-depth coverage of this tricky topic.
class Flight {
static mapping = {
batchSize 10
5.3.5 Pessimistic and Optimistic Locking
Optimistic LockingBy default GORM classes are configured for optimistic locking. Optimistic locking essentially is a feature of Hibernate which involves storing a version number in a special
version column in the database.The
version column gets read into a
version property that contains the current versioned state of persistent instance which you can access:
When you perform updates Hibernate will automatically check the version property against the version column in the database and if they differ will throw a StaleObjectException and the transaction will be rolled back.This is useful as it allows a certain level of atomicity without resorting to pessimistic locking that has an inherit performance penalty. The downside is that you have to deal with this exception if you have highly concurrent writes. This requires flushing the session:
def airport = Airport.get(10)println airport.version
The way you deal with the exception depends on the application. You could attempt a programmatic merge of the data or go back to the user and ask them to resolve the conflict.Alternatively, if it becomes a problem you can resort to pessimistic locking.
def airport = Airport.get(10)try { airport.name = "Heathrow" airport.save(flush:true) } catch(org.springframework.dao.OptimisticLockingFailureException e) { // deal with exception }
Pessimistic LockingPessimistic locking is equivalent to doing a SQL "SELECT * FOR UPDATE" statement and locking a row in the database. This has the implication that other read operations will be blocking until the lock is released.In Grails pessimistic locking is performed on an existing instance via the lock method:
Grails will automatically deal with releasing the lock for you once the transaction has been committed. However, in the above case what we are doing is "upgrading" from a regular SELECT to a SELECT..FOR UPDATE and another thread could still have updated the record in between the call to get() and the call to lock().To get around this problem you can use the static lock method that takes an id just like get:
def airport = Airport.get(10) airport.lock() // lock for update airport.name = "Heathrow" airport.save()
In this case only SELECT..FOR UPDATE is issued.
def airport = Airport.lock(10) // lock for update airport.name = "Heathrow" airport.save()
Though Grails, through Hibernate, supports pessimistic locking, the embedded HSQLDB shipped with Grails which is used as the default in-memory database does not. If you need to test pessimistic locking you will need to do so against a database that does have support such as MySQL.As well as the lock method you can also obtain a pessimistic locking using queries. For example using a dynamic finder:
Or using criteria:
def airport = Airport.findByName("Heathrow", [lock:true])
def airport = Airport.createCriteria().get {
eq('name', 'Heathrow')
lock true
5.3.6 Modification CheckingOnce you have loaded and possibly modified a persistent domain class instance, it isn't straightforward to retrieve the original values. If you try to reload the instance using get Hibernate will return the current modified instance from its Session cache. Reloading using another query would trigger a flush which could cause problems if your data isn't ready to be flushed yet. So GORM provides some methods to retrieve the original values that Hibernate caches when it loads the instance (which it uses for dirty checking).
isDirtyYou can use the isDirty method to check if any field has been modified:
You can also check if individual fields have been modified:
def airport = Airport.get(10) assert !airport.isDirty()airport.properties = params if (airport.isDirty()) { // do something based on changed state }
def airport = Airport.get(10) assert !airport.isDirty()airport.properties = params if (airport.isDirty('name')) { // do something based on changed name }
getDirtyPropertyNamesYou can use the getDirtyPropertyNames method to retrieve the names of modified fields; this may be empty but will not be null:
def airport = Airport.get(10) assert !airport.isDirty()airport.properties = params def modifiedFieldNames = airport.getDirtyPropertyNames() for (fieldName in modifiedFieldNames) { // do something based on changed value }
getPersistentValueYou can use the getPersistentValue method to retrieve the value of a modified field:
def airport = Airport.get(10) assert !airport.isDirty()airport.properties = params def modifiedFieldNames = airport.getDirtyPropertyNames() for (fieldName in modifiedFieldNames) { def currentValue = airport."$fieldName" def originalValue = airport.getPersistentValue(fieldName) if (currentValue != originalValue) { // do something based on changed value } }
5.4 Querying with GORMGORM supports a number of powerful ways to query from dynamic finders, to criteria to Hibernate's object oriented query language HQL.Groovy's ability to manipulate collections via GPath and methods like sort, findAll and so on combined with GORM results in a powerful combination.However, let's start with the basics.
Listing instancesIf you simply need to obtain all the instances of a given class you can use the list method:
The list method supports arguments to perform pagination:
def books = Book.list()
as well as sorting:
def books = Book.list(offset:10, max:20)
Here, the
def books = Book.list(sort:"title", order:"asc")
sort argument is the name of the domain class property that you wish to sort on, and the
order argument is either
asc for ascending or
desc for descending.
Retrieval by Database IdentifierThe second basic form of retrieval is by database identifier using the get method:
You can also obtain a list of instances for a set of identifiers using getAll:
def book = Book.get(23)
def books = Book.getAll(23, 93, 81)
5.4.1 Dynamic FindersGORM supports the concept of dynamic finders. A dynamic finder looks like a static method invocation, but the methods themselves don't actually exist in any form at the code level.Instead, a method is auto-magically generated using code synthesis at runtime, based on the properties of a given class. Take for example the
Book class:
class Book { String title Date releaseDate Author author } class Author { String name }
Book class has properties such as
releaseDate and
author. These can be used by the findBy and findAllBy methods in the form of "method expressions":
def book = Book.findByTitle("The Stand")book = Book.findByTitleLike("Harry Pot%")book = Book.findByReleaseDateBetween( firstDate, secondDate )book = Book.findByReleaseDateGreaterThan( someDate )book = Book.findByTitleLikeOrReleaseDateLessThan( "%Something%", someDate )
Method ExpressionsA method expression in GORM is made up of the prefix such as findBy followed by an expression that combines one or more properties. The basic form is:
The tokens marked with a '?' are optional. Each comparator changes the nature of the query. For example:
Book.findBy([Property][Comparator][Boolean Operator])?[Property][Comparator]
In the above example the first query is equivalent to equality whilst the latter, due to the
def book = Book.findByTitle("The Stand")book = Book.findByTitleLike("Harry Pot%")
Like comparator, is equivalent to a SQL
like expression.The possible comparators include:
InList- In the list of given values
LessThan- less than the given value
LessThanEquals- less than or equal a give value
GreaterThan- greater than a given value
GreaterThanEquals- greater than or equal a given value
Like- Equivalent to a SQL like expression
Ilike- Similar to a
Like, except case insensitive
NotEqual- Negates equality
Between- Between two values (requires two arguments)
IsNotNull- Not a null value (doesn't require an argument)
IsNull- Is a null value (doesn't require an argument)
def now = new Date()
def lastWeek = now - 7
def book = Book.findByReleaseDateBetween( lastWeek, now )books = Book.findAllByReleaseDateIsNull()
books = Book.findAllByReleaseDateIsNotNull()
Boolean logic (AND/OR)Method expressions can also use a boolean operator to combine two criteria:
In this case we're using
def books = Book.findAllByTitleLikeAndReleaseDateGreaterThan("%Java%", new Date()-30)
And in the middle of the query to make sure both conditions are satisfied, but you could equally use
At the moment, you can only use dynamic finders with a maximum of two criteria, i.e. the method name can only have one boolean operator. If you need to use more, you should consider using either Criteria or the HQL.
def books = Book.findAllByTitleLikeOrReleaseDateGreaterThan("%Java%", new Date()-30)
Querying AssociationsAssociations can also be used within queries:
In this case if the
def author = Author.findByName("Stephen King")def books = author ? Book.findAllByAuthor(author) : []
Author instance is not null we use it in a query to obtain all the
Book instances for the given
Pagination & SortingThe same pagination and sorting parameters available on the list method can also be used with dynamic finders by supplying a map as the final parameter:
def books = Book.findAllByTitleLike("Harry Pot%", [max:3, offset:2, sort:"title", order:"desc"])
5.4.2 CriteriaCriteria is a type safe, advanced way to query that uses a Groovy builder to construct potentially complex queries. It is a much better alternative to using StringBuffer.Criteria can be used either via the createCriteria or withCriteria methods. The builder uses Hibernate's Criteria API, the nodes on this builder map the static methods found in the Restrictions class of the Hibernate Criteria API. Example Usage:
This criteria will select up to 10
def c = Account.createCriteria() def results = c { between("balance", 500, 1000) eq("branch", "London") or { like("holderFirstName", "Fred%") like("holderFirstName", "Barney%") } maxResults(10) order("holderLastName", "desc") }
Account objects matching the following criteria:
balanceis between 500 and 1000
branchis 'London'
holderFirstNamestarts with 'Fred' or 'Barney'
Conjunctions and DisjunctionsAs demonstrated in the previous example you can group criteria in a logical OR using a
or { } block:
This also works with logical AND:
or { between("balance", 500, 1000) eq("branch", "London") }
And you can also negate using logical NOT:
and { between("balance", 500, 1000) eq("branch", "London") }
All top level conditions are implied to be AND'd together.
not { between("balance", 500, 1000) eq("branch", "London") }
Querying AssociationsAssociations can be queried by having a node that matches the property name. For example say the
Account class had many
Transaction objects:
We can query this association by using the property name
class Account {
static hasMany = [transactions:Transaction]
transaction as a builder node:
The above code will find all the
def c = Account.createCriteria()
def now = new Date()
def results = c.list {
transactions {
between('date',now-10, now)
Account instances that have performed
transactions within the last 10 days.
You can also nest such association queries within logical blocks:
Here we find all accounts that have either performed transactions in the last 10 days OR have been recently created in the last 10 days.
def c = Account.createCriteria()
def now = new Date()
def results = c.list {
or {
transactions {
between('date',now-10, now)
Querying with ProjectionsProjections may be used to customise the results. To use projections you need to define a "projections" node within the criteria builder tree. There are equivalent methods within the projections node to the methods found in the Hibernate Projections class:
def c = Account.createCriteria()def numberOfBranches = c.get { projections { countDistinct('branch') } }
Using SQL RestrictionsYou can access Hibernate's SQL Restrictions capabilities.
def c = Person.createCriteria()def peopleWithShortFirstNames = c.list {
sqlRestriction "char_length( first_name ) <= 4"
Note that the parameter there is SQL. The
first_nameattribute referenced in the example relates to the persistence model, not the object model. The
Personclass may have a property named
firstNamewhich is mapped to a column in the database named
first_name.Also note that the SQL used here is not necessarily portable across databases.
Using Scrollable ResultsYou can use Hibernate's ScrollableResults feature by calling the scroll method:
To quote the documentation of Hibernate ScrollableResults:
def results = crit.scroll {
def f = results.first()
def l = results.last()
def n = results.next()
def p = results.previous()def future = results.scroll(10)
def accountNumber = results.getLong('number')
A result iterator that allows moving around within the results by arbitrary increments. The Query / ScrollableResults pattern is very similar to the JDBC PreparedStatement/ ResultSet pattern and the semantics of methods of this interface are similar to the similarly named methods on ResultSet.Contrary to JDBC, columns of results are numbered from zero.
Setting properties in the Criteria instanceIf a node within the builder tree doesn't match a particular criterion it will attempt to set a property on the Criteria object itself. Thus allowing full access to all the properties in this class. The below example calls
setMaxResults and
setFirstResult on the Criteria instance:
import org.hibernate.FetchMode as FM … def results = c.list { maxResults(10) firstResult(50) fetchMode("aRelationship", FM.JOIN) }
Querying with Eager FetchingIn the section on Eager and Lazy Fetching we discussed how to declaratively specify fetching to avoid the N+1 SELECT problem. However, this can also be achieved using a criteria query:
Notice the usage of the
def criteria = Task.createCriteria()
def tasks = criteria.list{
eq "assignee.id", task.assignee.id
join 'assignee'
join 'project'
order 'priority', 'asc'
join method: it tells the criteria API to use a
JOIN to fetch the named associations with the
Task instances. It's probably best not to use this for one-to-many associations though, because you will most likely end up with duplicate results. Instead, use the 'select' fetch mode:
Although this approach triggers a second query to get the
import org.hibernate.FetchMode as FM … def results = Airport.withCriteria { eq "region", "EMEA" fetchMode "flights", FM.SELECT }
flights association, you will get reliable results - even with the
maxResults option.
An important point to bear in mind is that if you include associations in the query constraints, those associations will automatically be eagerly loaded. For example, in this query:
joinare general settings of the query and can only be specified at the top-level, i.e. you cannot use them inside projections or association constraints.
def results = Airport.withCriteria { eq "region", "EMEA" flights { like "number", "BA%" } }
flights collection would be loaded eagerly via a join even though the fetch mode has not been explicitly set.
Method ReferenceIf you invoke the builder with no method name such as:
The build defaults to listing all the results and hence the above is equivalent to:
c { … }
c.list { … }
|This is the default method. It returns all matching rows.
|Returns a unique result set, i.e. just one row. The criteria has to be formed that way, that it only queries one row. This method is not to be confused with a limit to just the first row.
|Returns a scrollable result set.
|If subqueries or associations are used, one may end up with the same row multiple times in the result set, this allows listing only distinct entities and is equivalent to
DISTINCT_ROOT_ENTITY of the CriteriaSpecification class.
|Returns the number of matching rows.
5.4.3 Hibernate Query Language (HQL)GORM classes also support Hibernate's query language HQL, a very complete reference for which can be found Chapter 14. HQL: The Hibernate Query Language of the Hibernate documentation.GORM provides a number of methods that work with HQL including find, findAll and executeQuery. An example of a query can be seen below:
def results =
Book.findAll("from Book as b where b.title like 'Lord of the%'")
Positional and Named ParametersIn this case the value passed to the query is hard coded, however you can equally use positional parameters:
def results = Book.findAll("from Book as b where b.title like ?", ["The Shi%"])
Or even named parameters:
def author = Author.findByName("Stephen King") def books = Book.findAll("from Book as book where book.author = ?", [author])
def results = Book.findAll("from Book as b where b.title like :search or b.author like :search", [search:"The Shi%"])
def author = Author.findByName("Stephen King") def books = Book.findAll("from Book as book where book.author = :author", [author: author])
Multiline QueriesIf you need to separate the query across multiple lines you can use a line continuation character:
def results = Book.findAll("\
from Book as b, \
Author as a \
where b.author = a and a.surname = ?", ['Smith'])
Groovy multiline strings will NOT work with HQL queries
Pagination and SortingYou can also perform pagination and sorting whilst using HQL queries. To do so simply specify the pagination options as a map at the end of the method call and include an "ORDER BY" clause in the HQL:
def results =
Book.findAll("from Book as b where b.title like 'Lord of the%' order by b.title asc",
[max:10, offset:20])
5.5 Advanced GORM FeaturesThe following sections cover more advanced usages of GORM including caching, custom mapping and events.
5.5.1 Events and Auto TimestampingGORM supports the registration of events as methods that get fired when certain events occurs such as deletes, inserts and updates. The following is a list of supported events:
beforeInsert- Executed before an object is initially persisted to the database
beforeUpdate- Executed before an object is updated
beforeDelete- Executed before an object is deleted
beforeValidate- Executed before an object is validated
afterInsert- Executed after an object is persisted to the database
afterUpdate- Executed after an object has been updated
afterDelete- Executed after an object has been deleted
onLoad- Executed when an object is loaded from the database
Do not attempt to flush the session within an event (such as with obj.save(flush:true)). Since events are fired during flushing this will cause a StackOverflowError.
Event types
The beforeInsert eventFired before an object is saved to the db
class Person {
Date dateCreated def beforeInsert() {
dateCreated = new Date()
The beforeUpdate eventFired before an existing object is updated
class Person { Date dateCreated Date lastUpdated def beforeInsert() { dateCreated = new Date() } def beforeUpdate() { lastUpdated = new Date() } }
The beforeDelete eventFired before an object is deleted.
Notice the usage of
class Person { String name Date dateCreated Date lastUpdated def beforeDelete() { ActivityTrace.withNewSession { new ActivityTrace(eventName:"Person Deleted",data:name).save() } } }
withNewSession method above. Since events are triggered whilst Hibernate is flushing using persistence methods like
save() and
delete() won't result in objects being saved unless you run your operations with a new
Session.Fortunately the
withNewSession method allows you to share the same transactional JDBC connection even though you're using a different underlying
The beforeValidate eventFired before an object is validated.
class Person { String name static constraints = { name size: 5..45 } def beforeValidate() { name = name?.trim() } }
beforeValidate method is run before any validators are run.GORM supports an overloaded version of
beforeValidate which accepts a
List parameter which may include
the names of the properties which are about to be validated. This version of
beforeValidate will be called
when the
validate method has been invoked and passed a
List of property names as an argument.
class Person { String name String town Integer age static constraints = { name size: 5..45 age range: 4..99 } def beforeValidate(List propertiesBeingValidated) { // do pre validation work based on propertiesBeingValidated } }def p = new Person(name: 'Jacob Brown', age: 10) p.validate(['age', 'name'])
Note that whenEither or both versions of
validateis triggered indirectly because of a call to the
savemethod that the
validatemethod is being invoked with no arguments, not a
Listthat includes all of the property names.
beforeValidate may be defined in a domain class. GORM will
prefer the
List version if a
List is passed to
validate but will fall back on the
no-arg version if the
List version does not exist. Likewise, GORM will prefer the
no-arg version if no arguments are passed to
validate but will fall back on the
List version if the no-arg version does not exist. In that case, null
is passed to
The onLoad/beforeLoad eventFired immediately before an object is loaded from the db:
class Person { String name Date dateCreated Date lastUpdated def onLoad() { log.debug "Loading ${id}" } }
beforeLoad() is effectively a synonym for
onLoad(), so only declare one or the other.
The afterLoad eventFired immediately after an object is loaded from the db:
class Person { String name Date dateCreated Date lastUpdated def afterLoad() { name = "I'm loaded" } }
Custom Event ListenersYou can also register event handler classes in an application's
grails-app/conf/spring/resources.groovy or in the
doWithSpring closure in a plugin descriptor by registering a Spring bean named
hibernateEventListeners. This bean has one property,
listenerMap which specifies the listeners to register for various Hibernate events.The values of the map are instances of classes that implement one or more Hibernate listener interfaces. You can use one class that implements all of the required interfaces, or one concrete class per interface, or any combination. The valid map keys and corresponding interfaces are listed here:
AuditEventListener which implements
PostUpdateEventListener, and
PostDeleteEventListener using the following in an application:
or use this in a plugin:
beans = { auditListener(AuditEventListener) hibernateEventListeners(HibernateEventListeners) { listenerMap = ['post-insert':auditListener, 'post-update':auditListener, 'post-delete':auditListener] } }
def doWithSpring = { auditListener(AuditEventListener) hibernateEventListeners(HibernateEventListeners) { listenerMap = ['post-insert':auditListener, 'post-update':auditListener, 'post-delete':auditListener] } }
Automatic timestampingThe examples above demonstrated using events to update a
lastUpdated and
dateCreated property to keep track of updates to objects. However, this is actually not necessary. By merely defining a
lastUpdated and
dateCreated property these will be automatically updated for you by GORM.If this is not the behaviour you want you can disable this feature with:
class Person { Date dateCreated Date lastUpdated static mapping = { autoTimestamp false } }
If you put
nullable: falseconstraints on either
lastUpdated, your domain instances will fail validation - probably not what you want. Leave constraints off these properties unless you have disabled automatic timestamping.
5.5.2 Custom ORM MappingGrails domain classes can be mapped onto many legacy schemas via an Object Relational Mapping Domain Specify Language. The following sections takes you through what is possible with the ORM DSL.
None if this is necessary if you are happy to stick to the conventions defined by GORM for table, column names and so on. You only needs this functionality if you need to in anyway tailor the way GORM maps onto legacy schemas or performs cachingCustom mappings are defined using a a static
mapping block defined within your domain class:
class Person {
static mapping = { }
188.8.131.52 Table and Column Names
Table namesThe database table name which the class maps to can be customized using a call to
In this case the class would be mapped to a table called
class Person {
static mapping = {
table 'people'
people instead of the default name of
Column namesIt is also possible to customize the mapping for individual columns onto the database. For example if its the name you want to change you can do:
In this case we define method calls that match each property name (in this case
class Person { String firstName static mapping = { table 'people' firstName column:'First_Name' } }
firstName). We then use the named parameter
column, to specify the column name to map onto.
Column typeGORM supports configuration of Hibernate types via the DSL using the type attribute. This includes specifing user types that subclass the Hibernate org.hibernate.usertype.UserType class, which allows complete customization of how a type is persisted. As an example if you had a
PostCodeType you could use it as follows:
Alternatively if you just wanted to map it to one of Hibernate's basic types other than the default chosen by Grails you could use:
class Address { String number String postCode static mapping = { postCode type:PostCodeType } }
This would make the
class Address { String number String postCode static mapping = { postCode type:'text' } }
postCode column map to the SQL TEXT or CLOB type depending on which database is being used.See the Hibernate documentation regarding Basic Types for further information.
Many-to-One/One-to-One MappingsIn the case of associations it is also possible to change the foreign keys used to map associations. In the case of a many- or one-to-one association this is exactly the same as any regular column. For example consider the following:
By default the
class Person { String firstName Address address static mapping = { table 'people' firstName column:'First_Name' address column:'Person_Address_Id' } }
address association would map to a foreign key column called
address_id. By using the above mapping we have changed the name of the foreign key column to
One-to-Many MappingWith a bidirectional one-to-many you can change the foreign key column used simple by changing the column name on the many side of the association as per the example in the previous section on one-to-one associations. However, with unidirectional association the foreign key needs to be specified on the association itself. For example given a unidirectional one-to-many relationship between
Person and
Address the following code will change the foreign key in the
address table:
If you don't want the column to be in the
class Person { String firstName static hasMany = [addresses:Address] static mapping = { table 'people' firstName column:'First_Name' addresses column:'Person_Address_Id' } }
address table, but instead some intermediate join table you can use the
joinTable parameter:
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'] } }
Many-to-Many MappingGrails, by default maps a many-to-many association using a join table. For example consider the below many-to-many association:
In this case Grails will create a join table called
class Group { … static hasMany = [people:Person] } class Person { … static belongsTo = Group static hasMany = [groups:Group] }
group_person containing foreign keys called
person_id and
group_id referencing the
person and
group tables. If you need to change the column names you can specify a column within the mappings for each class.
You can also specify the name of the join table to use:
class Group { … static mapping = { people column:'Group_Person_Id' } } class Person { … static mapping = { groups column:'Group_Group_Id' } }
class Group { … static mapping = { people column:'Group_Person_Id',joinTable:'PERSON_GROUP_ASSOCIATIONS' } } class Person { … static mapping = { groups column:'Group_Group_Id',joinTable:'PERSON_GROUP_ASSOCIATIONS' } }
22.214.171.124 Caching Strategy
Setting up cachingHibernate features a second-level cache with a customizable cache provider. This needs to be configured in the
grails-app/conf/DataSource.groovy file as follows:
You can of course customize these settings how you desire, for example if you want to use a distributed caching mechanism.
hibernate { cache.use_second_level_cache=true cache.use_query_cache=true cache.provider_class='org.hibernate.cache.EhCacheProvider' }
For further reading on caching and in particular Hibernate's second-level cache, refer to the Hibernate documentation on the subject.
Caching instancesIn your mapping block to enable caching with the default settings use a call to the
cache method:
This will configure a 'read-write' cache that includes both lazy and non-lazy properties. If you need to customize this further you can do:
class Person { .. static mapping = { table 'people' cache true } }
class Person {
static mapping = {
table 'people'
cache usage:'read-only', include:'non-lazy'
Caching associationsAs well as the ability to use Hibernate's second level cache to cache instances you can also cache collections (associations) of objects. For example:
This will enable a 'read-write' caching mechanism on the addresses collection. You can also use:
class Person { String firstName static hasMany = [addresses:Address] static mapping = { table 'people' version false addresses column:'Address', cache:true } } class Address { String number String postCode }
To further configure the cache usage.
cache:'read-write' // or 'read-only' or 'transactional'
Caching QueriesYou can cache queries such as dynamic finders and criteria. To do so using a dynamic finder you can pass the
cache argument:
def person = Person.findByFirstName("Fred", [cache:true])
Note that in order for the results of the query to be cached, you still need to enable caching in your mapping as discussed in the previous section.You can also cache criteria queries:
def people = Person.withCriteria {
like('firstName', 'Fr%')
cache true
Cache usagesBelow is a description of the different cache settings and their usages:
read-only- If your application needs to read but never modify instances of a persistent class, a read-only cache may be used.
read-write- If the application needs to update data, a read-write cache might be appropriate.
nonstrict-read-write- If the application only occasionally needs to update data (ie. if it is extremely unlikely that two transactions would try to update the same item simultaneously) and strict transaction isolation is not required, a
nonstrict-read-writecache might be appropriate.
transactional- The
transactionalcache strategy provides support for fully transactional cache providers such as JBoss TreeCache. Such a cache may only be used in a JTA environment and you must specify
hibernate.transaction.manager_lookup_classin the
220.127.116.11 Inheritance StrategiesBy default GORM classes uses
table-per-hierarchy inheritance mapping. This has the disadvantage that columns cannot have a
NOT-NULL constraint applied to them at the db level. If you would prefer to use a
table-per-subclass inheritance strategy you can do so as follows:
The mapping of the root
class Payment { Long id Long version Integer amount static mapping = { tablePerHierarchy false } } class CreditCardPayment extends Payment { String cardNumber }
Payment class specifies that it will not be using
table-per-hierarchy mapping for all child classes.
184.108.40.206 Custom Database IdentityYou can customize how GORM generates identifiers for the database using the DSL. By default GORM relies on the native database mechanism for generating ids. This is by far the best approach, but there are still many schemas that have different approaches to identity.To deal with this Hibernate defines the concept of an id generator. You can customize the id generator and the column it maps to as follows:
In this case we're using one of Hibernate's built in 'hilo' generators that uses a separate table to generate ids.
class Person { .. static mapping = { table 'people' version false id generator:'hilo', params:[table:'hi_value',column:'next_value',max_lo:100] } }
For more information on the different Hibernate generators refer to the Hibernate reference documentationNote that if you want to merely customise the column that the id lives on you can do:
class Person { .. static mapping = { table 'people' version false id column:'person_id' } }
188.8.131.52 Composite Primary KeysGORM supports the concept of composite identifiers (identifiers composed from 2 or more properties). It is not an approach we recommend, but is available to you if you need it:
The above will create a composite id of the
class Person { String firstName String lastName static mapping = { id composite:['firstName', 'lastName'] } }
firstName and
lastName properties of the Person class. When you later need to retrieve an instance by id you have to use a prototype of the object itself:
def p = Person.get(new Person(firstName:"Fred", lastName:"Flintstone")) println p.firstName
22.214.171.124 Database IndicesTo get the best performance out of your queries it is often necessary to tailor the table index definitions. How you tailor them is domain specific and a matter of monitoring usage patterns of your queries. With GORM's DSL you can specify which columns need to live in which indexes:
Note that you cannot have any spaces in the value of the
class Person { String firstName String address static mapping = { table 'people' version false id column:'person_id' firstName column:'First_Name', index:'Name_Idx' address column:'Address', index:'Name_Idx,Address_Index' } }
index attribute; in this example
index:'Name_Idx, Address_Index' will cause an error.
18.104.22.168 Optimistic Locking and VersioningAs discussed in the section on Optimistic and Pessimistic Locking, by default GORM uses optimistic locking and automatically injects a
version property into every class which is in turn mapped to a
version column at the database level.If you're mapping to a legacy schema this can be problematic, so you can disable this feature by doing the following:
class Person { .. static mapping = { table 'people' version false } }
If you disable optimistic locking you are essentially on your own with regards to concurrent updates and are open to the risk of users losing (due to data overriding) data unless you use pessimistic locking
126.96.36.199 Eager and Lazy Fetching
Lazy CollectionsAs discussed in the section on Eager and Lazy fetching, GORM collections are lazily loaded by default but you can change this behaviour via the ORM DSL. There are several options available to you, but the most common ones are:
- lazy: false
- fetch: 'join'
The first option,
class Person { String firstName Pet pet static hasMany = [addresses:Address] static mapping = { addresses lazy:false pet fetch: 'join' } }class Address { String street String postCode }class Pet { String name }
lazy: false , ensures that when a
Person instance is loaded, its
addresses collection is loaded at the same time with a second SELECT. The second option is basically the same, except the collection is loaded via a JOIN rather than another SELECT. Typically you will want to reduce the number of queries, so
fetch: 'join' will be the more appropriate option. On the other hand, it could feasibly be the more expensive approach if your domain model and data result in more and larger results than would otherwise be necessary.For more advanced users, the other settings available are:
- batchSize: N
- lazy: false, batchSize: N
If a query returns multiple
class Person { String firstName Pet pet static mapping = { pet batchSize: 5 } }
Person instances, then when we access the first
pet property, Hibernate will fetch that
Pet plus the four next ones. You can get the same behaviour with eager loading by combining
batchSize with the
lazy: false option. You can find out more about these options in the Hibernate user guide and this primer on fetching strategies. Note that ORM DSL does not currently support the "subselect" fetching strategy.
Lazy Single-Ended AssociationsIn GORM, one-to-one and many-to-one associations are by default lazy. Non-lazy single ended associations can be problematic when you load many entities because each non-lazy association will result in an extra SELECT statement. If the associated entities also have non-lazy associations, the number of queries grows exponentially!If you want to make a one-to-one or many-to-one association non-lazy/eager, you can use the same technique as for lazy collections:
Here we configure GORM to load the associated
class Person { String firstName }class Address { String street String postCode static belongsTo = [person:Person] static mapping = { person lazy:false } }
Person instance (through the
person property) whenever an
Address is loaded.
Lazy Single-Ended Associations and ProxiesIn order to facilitate single-ended lazy associations Hibernate uses runtime generated proxies. The way this works is that Hibernate dynamically subclasses the proxied entity to create the proxy.Consider the previous example but with a lazily-loaded
person association: Hibernate will set the
person property to a proxy that is a subclass of
Person. When you call any of the getters or setters on that proxy, Hibernate will load the entity from the database.Unfortunately this technique can produce surprising results. Consider the following example classes:
and assume that we have a single
class Pet { String name } class Dog extends Pet { } class Person { String name Pet pet }
Person instance with a
Dog as his or her
pet. The following code will work as you would expect:
But this won't:
def person = Person.get(1) assert person.pet instanceof Dog assert Pet.get(person.petId) instanceof Dog
For some reason, the second assertion fails. To add to the confusion, this will work:
def person = Person.get(1) assert person.pet instanceof Dog assert Pet.list()[0] instanceof Dog
What's going on here? It's down to a combination of how proxies work and the guarantees that the Hibernate session makes. When you load the
assert Pet.list()[0] instanceof Dog
Person instance, Hibernate creates a proxy for its
pet relation and attaches it to the session. Once that happens, whenever you retrieve that
Pet instance via a query, a
get(), or the
pet relation within the same session , Hibernate gives you the proxy.Fortunately for us, GORM automatically unwraps the proxy when you use
get() and
findBy*(), or when you directly access the relation. That means you don't have to worry at all about proxies in the majority of cases. But GORM doesn't do that for objects returned via a query that returns a list, such as
list() and
findAllBy*(). However, if Hibernate hasn't attached the proxy to the session, those queries will return the real instances - hence why the last example works.You can protect yourself to a degree from this problem by using the
instanceOf method by GORM:
However, it won't help here casting is involved. For example, the following code will throw a
def person = Person.get(1) assert Pet.list()[0].instanceOf(Dog)
ClassCastException because the first pet in the list is a proxy instance with a class that is neither
Dog nor a sub-class of
Of course, it's best not to use static types in this situation. If you use an untyped variable for the pet instead, you can access any
def person = Person.get(1) Dog pet = Pet.list()[0]
Dog properties or methods on the instance without any problems.These days it's rare that you will come across this issue, but it's best to be aware of it just in case. At least you will know why such an error occurs and be able to work around it.
126.96.36.199 Custom Cascade BehaviourAs describes in the section on cascading updates, the primary mechanism to control the way updates and deletes are cascading from one association to another is the belongsTo static property.However, the ORM DSL gives you complete access to Hibernate's transitive persistence capabilities via the
cascade attribute.Valid settings for the cascade attribute include:
- merge - merges the state of a detached association
- save-update - cascades only saves and updates to an association
- delete - cascades only deletes to an association
- lock - useful if a pessimistic lock should be cascaded to its associations
- refresh - cascades refreshes to an association
- evict - cascades evictions (equivalent to discard() in GORM) to associations if set
- all - cascade ALL operations to associations
- all-delete-orphan - Applies only to one-to-many associations and indicates that when a child is removed from an association then it should be automatically deleted. Children are also deleted when the parent is.
It is advisable to read the section in the Hibernate documentation on transitive persistence to obtain a better understanding of the different cascade styles and recommendation for their usageTo specific the cascade attribute simply define one or many (comma-separated) of the aforementioned settings as its value:
class Person { String firstName static hasMany = [addresses:Address] static mapping = { addresses cascade:"all-delete-orphan" } } class Address { String street String postCode }
22.214.171.124 Custom Hibernate TypesYou saw in an earlier section that you can use composition (via the
embedded property) to break a table into multiple objects. You can achieve a similar effect via Hibernate's custom user types. These are not domain classes themselves, but plain Java or Groovy classes with associated. Each of these types also has a corresponding "meta-type" class that implements org.hibernate.usertype.UserType.The Hibernate reference manual has some information on custom types, but here we will focus on how to map them in Grails. Let's start by taking a look at a simple domain class that uses an old-fashioned (pre-Java 1.5) type-safe enum class:
All we have done is declare the
class Book { String title String author Rating rating static mapping = { rating type: RatingUserType } }
rating field the enum type and set the property's type in the custom mapping to the corresponding
UserType implementation. That's all you have to do to start using your custom type. If you want, you can also use the other column settings such as "column" to change the column name and "index" to add it to an index.Custom types aren't limited to just a single column - they can be mapped to as many columns as you want. In such cases you need to explicitly define in the mapping what columns to use, since Hibernate can only use the property name for a single column. Fortunately, Grails allows you to map multiple columns to a property using this syntax:
The above example will create "first_name" and "last_name" columns for the
class Book { String title Name author Rating rating static mapping = { name type: NameUserType, { column name: "first_name" column name: "last_name" } rating type: RatingUserType } }
author property. You'll be pleased to know that you can also use some of the normal column/property mapping attributes in the column definitions. For example:
The column definitions do not support the following attributes:
column name: "first_name", index: "my_idx", unique: true
cache, and
joinTable.One thing to bear in mind with custom types is that they define the SQL types for the corresponding database columns. That helps take the burden of configuring them yourself, but what happens if you have a legacy database that uses a different SQL type for one of the columns? In that case, you need to override column's SQL type using the
sqlType attribute:
Mind you, the SQL type you specify needs to still work with the custom type. So overriding a default of "varchar" with "text" is fine, but overriding "text" with "yes_no" isn't going to work.
class Book { String title Name author Rating rating static mapping = { name type: NameUserType, { column name: "first_name", sqlType: "text" column name: "last_name", sqlType: "text" } rating type: RatingUserType, sqlType: "text" } }
126.96.36.199 Derived PropertiesA derived property is a property that takes its value from a SQL expression, often but not necessarily based on the value of some other persistent property. Consider a Product class like this:
If the
class Product { Float price Float taxRate Float tax }
tax property is derived based on the value of
price and
properties then there may be no need to persist the
tax property in the
database. The SQL used to derive the value of a derived property may be
expressed in the ORM DSL like this:
Note that the formula expressed in the ORM DSL is SQL so references to other properties should relate to the persistence model not the object model, which is why the example refers to
class Product { Float price Float taxRate Float tax static mapping = { tax formula: 'PRICE * TAX_RATE' } }
PRICE and
TAX_RATE instead of
price and
taxRate.With that in place, when a Product is retrieved with something like
Product.get(42), the SQL that is generated to support
that will look something like this:
Since the
select product0_.id as id1_0_, product0_.version as version1_0_, product0_.price as price1_0_, product0_.tax_rate as tax4_1_0_, product0_.PRICE * product0_.TAX_RATE as formula1_0_ from product product0_ where product0_.id=?
tax property is being derived at runtime and not stored in the
database it might seem that the same effect could be achieved by adding
a method like
getTax() to the
Product class that simply returns the
product of the
taxRate and
price properties. With an approach like
that you would give up the ability query the database based on the value
of the
tax property. Using a derived property allows exactly that. To
retrieve all
Product objects that have a
tax value greater than 21.12
you could execute a query like this:
Derived properties may be referenced in the Criteria API:
The SQL that is generated to support either of those would look something like this:
Product.withCriteria { gt 'tax', 21.12f }
select this_.id as id1_0_, this_.version as version1_0_, this_.price as price1_0_, this_.tax_rate as tax4_1_0_, this_.PRICE * this_.TAX_RATE as formula1_0_ from product this_ where this_.PRICE * this_.TAX_RATE>?
Note that because the value of a derived property is generated in the database and depends on the execution of SQL code, derived properties may not have GORM constraints applied to them. If constraints are specified for a derived property, they will be ignored.
126.96.36.199 Custom Naming StrategyBy default Grails uses Hibernate's
ImprovedNamingStrategy to convert domain class Class and field names to SQL table and column names by converting from camel-cased Strings to ones that use underscores as word separators. You can customize these on a per-instance basis in the
mapping closure but if there's a consistent pattern you can specify a different
NamingStrategy class to use.Configure the class name to be used in
grails-app/conf/DataSource.groovy in the
hibernate section, e.g.
You can use an existing class or write your own, for example one that prefixes table names and column names:
dataSource { pooled = true dbCreate = "create-drop" … }hibernate { cache.use_second_level_cache = true … naming_strategy = com.myco.myproj.CustomNamingStrategy }
package com.myco.myprojimport org.hibernate.cfg.ImprovedNamingStrategy import org.hibernate.util.StringHelperclass CustomNamingStrategy extends ImprovedNamingStrategy { String classToTableName(String className) { "table_" + StringHelper.unqualify(className) } String propertyToColumnName(String propertyName) { "col_" + StringHelper.unqualify(propertyName) } }
5.5.3 Default Sort OrderYou can sort objects using queries arguments such as those found in the list method:
However, you can also declare the default sort order for a collection in the mapping:
def airports = Airport.list(sort:'name')
The above means that all collections of
class Airport { … static mapping = { sort "name" } }
Airports will be sorted by default by the airport name. If you also want to change the sort order , use this syntax:
Finally, you can configure the sorting at the association level:
class Airport { … static mapping = { sort name:"desc" } }
In this case, the
class Airport { … static hasMany = [flights:Flight] static mapping = { flights sort:'number', order:'desc' } }
flights collection will always be sorted in descending order of flight number.
These mappings will not work for default unidirectional one-to-many or many-to-many relationships because they involve a join table. See this issue for more details. Consider using a
SortedSet or queries with sort parameters to fetch the data you need.
5.6 Programmatic TransactionsGrails is built on Spring and hence uses Spring's Transaction abstraction for dealing with programmatic transactions. However, GORM classes have been enhanced to make this more trivial through the withTransaction method which accepts a block the first argument to which is the Spring TransactionStatus object.A typical usage scenario is as follows:
In this example we rollback the transactions if the destination account is not active and if any exception are thrown during the process the transaction will automatically be rolled back.You can also use "save points" to rollback a transaction to a particular point in time if you don't want to rollback the entire transaction. This can be achieved through the use of Spring's SavePointManager interface.The withTransaction method deals with the begin/commit/rollback logic for you within the scope of the block.
def transferFunds = { Account.withTransaction { status -> def source = Account.get(params.from) def dest = Account.get(params.to) def amount = params.amount.toInteger() if(source.active) { source.balance -= amount if(dest.active) { dest.amount += amount } else { status.setRollbackOnly() } } }}
5.7 GORM and ConstraintsAlthough constraints are covered in the Validation section, it is important to mention them here as some of the constraints can affect the way in which the database schema is generated.Where feasible, Grails uses a domain class's constraints to influence the database columns generated for the corresponding domain class properties.Consider the following example. Suppose we have a domain model with the following property.
By default, in MySQL, Grails would define these columns as...
String name String description
But perhaps the business rules for this domain class state that a description can be up to 1000 characters in length. If that were the case, we'd likely define the column as follows if we were creating the table via an SQL script.
column name | data type description | varchar(255)
Chances are we'd also want to have some application-based validation to make sure we don't exceed that 1000 character limit before we persist any records. In Grails, we achieve this validation via constraints. We'd add the following constraint declaration to the domain class.
column name | data type description | TEXT
This constraint would provide both the application-based validation we want and it would also cause the schema to be generated as shown above. Below is a description of the other constraints that influence schema generation.
static constraints = {
Constraints Affecting String Properties
maxSize or the
size constraint is defined, Grails sets the maximum column length based on the constraint value.In general, it's not advisable to use both constraints on the same domain class property. However, if both the
maxSize constraint and the
size constraint are defined, then Grails sets the column length to the minimum of the
maxSize constraint and the upper bound of the size constraint. (Grails uses the minimum of the two, because any length that exceeds that minimum will result in a validation error.)If the inList constraint is defined (and the
maxSize and the
size constraints are not defined), then Grails sets the maximum column length based on the length of the longest string in the list of valid values. For example, given a list including values "Java", "Groovy", and "C++", Grails would set the column length to 6 (i.e., the number of characters in the string "Groovy").
Constraints Affecting Numeric Properties
max constraint, the
min constraint, or the
range constraint is defined, Grails attempts to set the column precision based on the constraint value. (The success of this attempted influence is largely dependent on how Hibernate interacts with the underlying DBMS.)In general, it's not advisable to combine the pair min/max and range constraints together on the same domain class property. However, if both of these constraints is defined, then Grails uses the minimum precision value from the constraints. (Grails uses the minimum of the two, because any length that exceeds that minimum precision will result in a validation error.)
scale based on the constraint value. This rule only applies to floating point numbers (i.e., java.lang.Float, java.Lang.Double, java.lang.BigDecimal, or subclasses of java.lang.BigDecimal). (The success of this attempted influence is largely dependent on how Hibernate interacts with the underlying DBMS.)The constraints define the minimum/maximum numeric values, and Grails derives the maximum number of digits for use in the precision. Keep in mind that specifying only one of min/max constraints will not affect schema generation (since there could be large negative value of property with max:100, for example), unless specified constraint value requires more digits than default Hibernate column precision is (19 at the moment). For example...
would yield:
someFloatValue(max:1000000, scale:3)
someFloatValue DECIMAL(19, 3) // precision is default
would yield:
someFloatValue(max:12345678901234567890, scale:5)
someFloatValue DECIMAL(25, 5) // precision = digits in max + scale
would yield:
someFloatValue(max:100, min:-100000)
someFloatValue DECIMAL(8, 2) // precision = digits in min + default scale


text:
There are cases where an existing question overlaps almost perfectly with my needs, but it still does not satisfy my requirements.
What is the best course of action?
- ask a new question, referencing the previous one?
- edit the original question? ( sounds like a really bad idea )
- comment on the new question?
As a sample, I've asked catch-all smtp server with gui, which is closely related to dummy smtp server for testing apps that send email.

subset: commoncrawl


text:
TPM breaks down attacks on Census WorkersWednesday, June 23rd, 2010
Interesting article from TPM Muckraker:
There were 409 threats or assaults on Census workers making home visits between May and last Friday, 24 of which were animal attacks and 13 of which involved shots fired, according to data given to TPMmuckraker by the Census Bureau.
The Washington Post had a good story Sunday looking at the hazards of Census work. The paper noted that this year has seen more than double the 181 incidents reported last time around, in 2000.
Census Spokeswoman Shelly Lowe tells us in an email that the jump "is due in part to an increase in households and a more rigorous tracking system."
Here's the breakdown of the 409 incidents so far:
- In 10 cases the Census worker was robbed, carjacked, or held against his or her will.
- In 13 cases shots were fired.
- There were 24 animal attacks or threats.
- There were 101 verbal assaults or threats.
- In 132 cases a weapon was pulled or use of a weapon was threatened.
There were 88 physical assaults.


text:
898 members1890 Comments 117 Likes
974 members4873 Comments 32 Likes
Miranda Ramsey Evans has not received any gifts yet
Posted on March 8, 2013 at 8:30pm 0 Comments 0 Likes
Sixteen and pregnant. No. Seventeen and pregnant. Yes, that was me. Graduating high school with a bun in the oven or like most say "babies having babies." As soon as that cat was out of the bag, so were all the untamed tongues. Of course, being a pregnant teen wasn't right but people are so quick to make rash judgements. They will write you off before the mustard seed has time to turn into a fetus. I knew I was wrong, but just because I sinned differently than the next person didn't…Continue
Posted on March 5, 2013 at 3:18pm 0 Comments 0 Likes
Did you comb your hair, AJ? Cate, do you have your clothes on? We always pick out clothes the night before, sometimes for the whole week. This way we are prepared and I can make sure they match. We don't have time for anyone coming into the kitchen with red leggings on, an orange and yellow plaid dress, blue socks, a sparkly headband and twinkle toes. Maybe she'll be an artist one day, a very colorful one. I go through this routine every morning as we are getting ready for school. I…Continue
Posted on February 27, 2013 at 4:32pm 0 Comments 0 Likes
Fred Shuttlesworth,(1922-2011), was the pastor of the Birmingham, Alabama First Baptist Church who worked alongside Dr. Martin Luther King Jr. He organized the Alabama Christian Movement for Human Rights in 1956 and also helped head the movement to integrate Birmingham's schools, offices, and public facilities. This was my latest facebook status as I had declared to not only educate myself and family but all of my facebook world on the great African Americans in history throughout the…Continue
Hi there and welcome from The Girlz Korner where you'll find light, witty and rather entertaining articles on every topic imaginable from beauty, health, fashion, parenting, recipes and everything else in between. So if you get a chance to kick back and exhale, if only for a brief moment, we'd love to have you. Hope you enjoy your stay :) http://www.thegirlzkorner.com


text:
Microsoft/Nokia Deal Closes
Written by admin No Comments
Last Updated: April 25, 2014
Last September Microsoft announced it would be purchasing Nokia's Devices and Services business. The terms have been worked out, the shareholders gave approval, and the regulatory issues were hurdled. As of today, it's official: Nokia's phone business is now Microsoft Mobile. The final price is around $7.5 billion, and 30,000 employees are transferring to Microsoft. "The purchase of the unprofitable division makes Microsoft the world's second-largest maker of mobile phones with about 14 percent of the market, according to researcher IDC." Here's Nokia's official statement, and a rather more personal one from an employee. According to The Verge, "Nokia's Android handsets are the most intriguing part of the deal, as they shed some light on how Microsoft might approach the messy and complex nature of shipping devices that don't run the company's Windows software. The Nokia X introduces a new "forked" version of Android that's akin to what Amazon does with its Kindle Fire line, but it also includes a Windows Phone-like UI and an Android store that's separate to Google Play. Microsoft has the chance to control another app store, but also a solid opportunity to push its own cloud-based services." One interesting note: Nokia's phone manufacturing plant in India is not part of the deal because of an ongoing tax dispute. Nokia will continue to operate it as a contract manufacturing unit for Microsoft.
Read more of this story at Slashdot.


text:
The mission of the Crestview Police Department is to provide the community with the highest quality of life possible through enhanced, professional law enforcement services. In pursuit of the achievement of our mission the Crestview Police Department will proactively and responsively strive to protect our citizens from crime through effective and efficient delivery of services; and through partnerships with members of the community working toward our common goals and objectives. The Crestview Police Department is further committed, without prejudice, to protecting the liberties of all those we encounter, and preserving the inalienable rights of all citizens guaranteed by the Constitution of the United States of America.
The dedicated officers of the Crestview Police Department are committed to providing the citizens of the City of Crestview with the very best law enforcement services possible. We strongly believe in community-oriented public service and we are continually striving to cultivate more community partnerships. We are always seeking ways and means of efficiently and effectively enhancing our services and welcome your suggestions. Our doors are open to our community 24 hours a day, 7 days a week, 365 days a year.
Crestview, Florida is truly a one of a kind community with a collective, proverbial heart larger than imaginable. Words cannot fully express the sense of pride the Crestview Police Department has for the community we serve. We are grateful for the support of, and positive relationship we have with, the community. We are pleased and humbled to serve you.
Please keep us in your daily prayers, as you are kept in ours.


text:
Chic in Arabi
Post-Hurricane Katrina revival created new opportunities
Hurricane Katrina's water rose eight feet in Harold Applewhite's Arabi home, located just blocks from the Mississippi River. It was a sorry mess when he returned a couple of weeks after the storm. "When I first pushed in the front door and looked inside it seemed like a hopeless situation," he says. But he's not one to cut and run; he dug in his heels, determined to fix up his house and make it better than ever.
Applewhite is the owner of Harold's Indoor & Outdoor Plants, located where Press Street and the railroad tracks cross St. Claude Avenue. Applewhite's business has long been the place to find one of the most extensive collections of plants and flowers in the area. "Katrina also decimated my nursery and shop," he says, adding that it was a $100,000 loss.
Two strikes, but not out. Not only did he come back with a better business than he had before the storm, he also restored his home and garden and purchased the two homes adjoining his property on a quiet residential street.
"'What would you give me for my house?' my neighbor asked when she viewed her hurricane damage. 'How about $60,000?' was my answer. 'Sold,' she replied without batting an eye. As soon as my other adjoining neighbor heard about the transaction, he approached me about purchasing his home for the same amount. I immediately cut a deal."
Applewhite has created a compound out of the three Arabi homes. The unique maze of properties is joined by gardens, a brook, a saltwater swimming pool, decks, a gazebo and lush flowering gardens. There is a touch of whimsy embodied by a life-sized junk-metal sculpture of a man, and a touch of elegance provided by a crystal chandelier (from a French Quarter shop) that hangs in the gazebo.
"My backyard is a bit of paradise," he says. He adds that he likes wandering in the gardens and meeting the short-term guests who occupy the other houses. "This is the place I love to come after working long hours." Perry Stelly, who takes care of the plants at the Windsor Court Hotel, assisted him with his garden.
The vigorous, hardworking plant aficionado loves giving tours of his garden with Hartley, his Jack Russell terrier, at his side. "You will notice I use pine straw as a ground cover because my yard is too shady for grass, but the front garden is always filled with blooming flowers because it gets the wonderful morning sun."
Inside Applewhite's home is a handsome mix of bold-colored walls, eclectic furnishings and an art collection. "I even have a wonderful original by Walter Anderson in my den, my favorite room in the house," he says. He credits Bob Lowe for helping him select paint throughout the house.
"This house fits me like a glove," Applewhite says. "Most of all, I love living in Arabi where the folks are friendly and look out for each other."


text:
Event Calendar
Click the event for more details! Contact us if you're interested in an upcoming event. Our ministry seeks to bring the WORD of HIS GLORY to the world.
- This event has passed.
Take 5 Spring Break out
March 19 @ 4:30 pm - 5:30 pm EDT
**NOTE: All times are US Eastern Time Zone


text:
Great online shop and service folks! Have major gripe that R2 "Key to Time" Box Set has been SEVERELY limited and is in fact deleted already! There must be thousands of us who were budgeting to buy that - and many other Who dvds - and now it's gone already. Any chance at all that BBC will issue a second edition, for the many who have missed out completely, on this item?
Keep up the good work, people!
Galaxy 4 replies:
The Key To Time DVD set was released and advertised as a limited edition of 15,000. Because of this it cannot be re-issued once all the 15,000 units have been sold. The six stories from the set may be released individually next year at the regular price of �19.99 each. The box set was at a special price. An American Region 1 version (without special features) is still available.
i LOVE galaxy 4. It is a great informant on new stuff and has great prices.
G4 your excellent next day service made my sons 7th birthday perfect. Thankyou
G4, your service has always first rate. Its not just that processing and delivery is always efficient, I am always made to feel welcome in the shop or when I speak to you on the phone. Whenever I am looking for advice on products - old or new - that advice is always both friendly and forthcoming.
many thanks
What a fantastic service!! Placed my order Wednesday night, received my goods Friday morning. My son will be over the moon when he receives his Ood. Merry Christmas
I was over the moon when i discovered that the 12" Ood would be on sale on the 20th of December and promptly placed my pre-order.I was worried that my order would not arrive in time for Christmas but I received an e-mail at 3pm on 20th December to say that my order had been shipped and received my Ood at 2pm on 21st December!I am overjoyed!Your service is very fast and efficient and I will certainly be shopping with you again in the near future. Thank you so much Galaxy 4 for making this my 8 year old son's best Christmas ever!
I am so pleased with the service and delivery of Doctor Who items from G4. Sometimes I received my G4 items long before some of the companies in the States delivers them. Fast and reliable. a company I trust for my Dr. Who products.
First time customer. Fantastic delivery service and excellent goods. Will be returning soon. Im getting in early for christmas and I know one little boy that will be very happy in my household. Thanks again.
Galaxy 4 delivered my Season 2 DVD box set to new york in the blink of an eye...i`ll never have to feel homesick for old blighty and the good Doctor again..
Wow!! Galaxy 4 are fantastic.. absolutly fantastic! Prompt, friendly replies to e-mails.. delivery so fast are they sure they don`t travel in time?
Ordered items before of other sites and had problems. Never had one problem with Galaxy 4! Thank you xx
Ordered over the phone on a tuesday at about 4pm. Got it in the post the following morning 9am in aberdeen. Brilliant service.
As is probably more than borne out by the number of orders I have placed over the last couple of years, Galaxy Four are, bar none, my absolute favourite online store. The quickest and most efficient service on the face of the planet. Very often next day delivery. Fantastic!


text:
Rehabilitating a heritage building
For this project, Bluebird provided structural rehabilitation to the foundation walls and footings in a downtown heritage building.
The people to see your project through.
People are the cornerstone of our business. Our long-term employees provide a wealth of expertise and high standards of workmanship in earthworks and demolition services. We're there at the start of every project, taking ideas from the drawing board and implementing them with efficiency and safety.
A range of services. A wealth of experience.
At Bluebird, we know that the most important step of any project is the first step. Whatever the project, we put the needs of our clients first, with a strong dedication to the safety and best interest of the project at hand.
The first step is the most important.
Bluebird Contracting Services is a full-service earthworks and demolition contractor completing quality projects for agricultural, rail, residential, commercial, and industrial clients across Western Canada. Delivering projects on time and on budget, with a reputation for quality and safety built over 40 years. Bluebird's services are backed by extensive project experience, specialized equipment, and dedicated personnel.l.
At Bluebird, we have the people and expertise to handle any challenge. This expertise ensures that any size project can be completed safely and efficiently, and our comprehensive fleet of heavy equipment allows us to undertake multiple projects at once.
Being part of the Trotter & Morton Group of Companies, now Western Canada's leading multi-disciplined contractor, means we're associated with a number of organizations and associations within our industries. These new relationships have allowed us to expand our territory as we work hard to be a leader in the construction industry.
See what else we can do in Earthworks, Demolition, Underground Services, Asphalt Paving, and Rail Construction and Maintenance services.
Request a QuoteSee Our Projects
Bulk Excavation & Backfill
Bluebird is ranked as one of the leading excavation contractors in southern Alberta. This is in large part due to our experienced team, our comprehensive fleet of equipment, and our impressive performance records in both safety and operations.
With innovative techniques and extensive experience, Bluebird is an industry leader in providing large and small-scale demolition services. This includes residential, commercial and industrial projects, with our broad inventory of equipment allowing completion of all projects safely and efficiently.
On-call Emergency Services
Bluebird maintains a strong relationship with the City of Calgary Fire Department, working closely to provide equipment and skilled operators for emergency situations. Bluebird's specially trained operators also assist in cause and origin fire investigations.
Site Services
Our experienced crews and management team provide expertise in underground utility installation. We focus on quality control and safety while implementing effective procedures and techniques to meet the needs of our clients, even in the most challenging projects.
Civil Infrastructure,
Bluebird has a versatile workforce, allowing us to work in partnership with large and small scale infrastructure projects.
Structural Rehabilitation & Renovations
Working closely with industry partners, Bluebird has provided rehabilitation to structural columns, concrete slabs and foundation systems. We have participated in selective demolition and rebuild to update facilities, with a project management team and in-house engineers providing site-specific expertise.
Site Remediation & Environmental Services
Through proven techniques and specialized equipment, we provide effective, environmentally sound solutions for our clients. With extensive hands-on experience, Bluebird has built a reputation for reliability in underground storage tank removal, land farming impacted soils, and hazardous material cleanup.
Rail Construction & Maintenance
Partnering with our Earthworks division and equipped with a new fleet of rail equipment, Bluebird's team of experienced railroad personnel is capable of providing high-quality rail solutions for clients in a wide range of industries. From Class I Railroads to Light Rail Transit, our team is prepared to deliver any rail construction or maintenance project on time and on budget.
Bluebird Contracting Services


text:
We really enjoyed it. It wasn't too difficult, but it uses technology in a lot of interesting ways.
First time in an escape room was a bit difficult but the game master gave us extra time and we completed it. Was great fun !
Was very innovative never been to an escape room like it before would very much recommend it to young adults
Super fun & super clever! Would recommend! Came with my partner for her birthday and she loved it, it was her first escape room!
We did this as a work Team build so booked as 2 smaller teams to add a bit of competition.
It was so much fun. Genuinely laughed a lot. Great to see my colleagues in a different light.
I think the puzzles were a good level of challenging and solvable with in the team dynamic. The distance covered in walking may be a bit of a stretch for some but is doable.
Great value for money and I would highly recommend it for any occasion.
Hope to do another at some point soon.
Enjoyable experience with friends, gets you out and exploring the park and the puzzles are a fun and at a good level.
Worth the experience! First time doing an escape room and would definitely do it again! Escaped with a minute to spare!


text: Due to popular demand, two dates have been added to National Aquarium's 2013 Fresh Thoughts Sustainable Seafood Dining Series. Chefs from Ryleigh's Oyster House and The Capital Grille are set to headline the additional events in September and November of 2013. Each dinner of the series is themed around sustainable seafood, and will feature a cocktail reception, cooking demonstration by the guest chef, and a fine dining experience that includes a four-course menu created solely for the event. Guests are invited to come early to explore the exhibits, including the new Blacktip Reef exhibit, which will open in early August. Ryleigh's Oyster House, located in historic Federal Hill, specializes in serving fresh, quality seafood, meat, poultry, and produce in a comfortable relaxed atmosphere. The restaurant has been recognized by the Restaurant Association of Maryland as one of the "Stars of the Industry" and received praise from The Baltimore Sun, Baltimore City Paper and WJZ. Executive Chef Patrick Morrow will host an oyster-themed dinner on September 24, 2013. The Capital Grille, located in Baltimore's Inner Harbor, is famous for its dry-ages steaks, exceptional seafood and award-winning wine list. The restaurant has been named to OpenTable's Best American Cuisine Top 50 List, and has received accolades from WineSpectator and UrbanSpoon. The Capitol Grille will host a dinner on November 19, 2013. Previous guest chefs from the 2013 series include Bruce Clarke (Laurrapin Grille), Matthew Seigmund (The Oregon Grille) and Chris Becker (Fleet Street Kitchen). Over the years, National Aquarium has welcomed such celebrated chefs as James Beard Award nominee Bryan Voltaggio (VOLT), Jason Ambrose (Salt), Top Chef Timothy Dean, Chad Wells (Alewife), Top Chef Jessie Sandlin (Vino Rosino), Top Chef Jill Snyder, John Shields (Gertrude's), Antonio Baines (Tapas Teatro), Top Chef Tamesha Warren (The Oval Room), Galen Sampson (The Dogwood) and Mark Miranda (Rusty Scupper). Tickets for each dinner are $79 for National Aquarium members and $99 for non-members. Tickets for the September 14 and November 19 dinners can be purchased at www.aqua.org beginning August 1 or by calling 410-576-3869. Fresh Thoughts Sustainable Seafood Dining Series dinners take place at 6:30 p.m. at National Aquarium, Baltimore located at 501 E. Pratt Street, Baltimore, MD 21202. National Aquarium is proud to partner with Classic Catering for the Fresh Thoughts Sustainable Seafood Dining Series. Categories: