A domain class fulfills the M in the Model View Controller (MVC) pattern and represents a persistent entity that is mapped onto an underlying database table. This class will map automatically to a table in the database called book (the same name as the class). This behaviour is customizable through the ORM Domain. GORM is Grails’ object relational mapping (ORM) implementation, which sits on top of the very popular Hibernate framework. If you are familiar.
||20 May 2011
|PDF File Size:
|ePub File Size:
||Free* [*Free Regsitration Required]
Table of contents 1 Introduction. Table of Contents 6.
hibernate – How do you bulk delete records in Grails/GORM? – Stack Overflow
String name String description. Copies of this gor, may be made for your own yrails and for distribution to others, provided that you do not charge grrails fee for such copies and further provided that each copy contains this Grakls Notice, whether distributed in print or electronically. They hold state about business processes and hopefully also implement behavior.
They are linked together through relationships; one-to-one, one-to-many, or many-to-many. Under the gom it uses Hibernate 3 a very popular and flexible open source ORM solution and thanks to the dynamic nature of Groovy with its static and dynamic typing, along with the convention of Grails, there is far less configuration involved in creating Grails domain classes. You can also write Grails domain classes in Java.
See the section on Hibernate Integration for how to write domain classes in Java but still use dynamic persistent methods. Below is a preview of GORM in action: Graiks If no package is specified with the create-domain-class script, Grails automatically uses the application name as the package name. You can customize the class by adding properties: Create Torm create a domain class use Map constructor to set its properties and call save: Read Grails transparently adds an implicit id property to your domain class which you can use for retrieval: You can also load an object in a read-only gor, by using the read method: 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 a proxy for an instance by using the load method: Hibernate then initializes the proxied instance, or throws an exception if no record is found for the specified id. Update To update an instance, change some properties and then call save again: For example if you were building an Amazon -style bookstore you would be thinking about books, authors, customers and publishers to name a few. The next few sections show how to model the domain in GORM. To create a domain class you run the create-domain-class command as follows: Unless specified explicitly at both ends, a relationship exists only in the direction it is defined.
To make this relationship bidirectional define the other side as follows and see the section on controlling the ends of the association just below: The result of this is that we yorm create a Faceattach 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 Nose: Note that the inverse is not true and will result in an error due to a transient Face: Also, hasOne only works with bidirectional relationships.
Finally, it’s a good idea to add a grrails constraint on one side of the one-to-one relationship: They may even be self-referential, i.
GORM 6 – A powerful Groovy-based data access toolkit for the JVM
Such situations can cause problems because Grails may guess incorrectly the type of the association. Consider this simple class: So when you set the parent property on a Person instance, Grails will automatically set gdails supervisor property on the other Person instance. This may be what you want, but if you look at the class, what we in fact have are two unidirectional relationships. To guide Grails to the correct mapping, you can tell it that a particular association is graila through the graips property: And of course this works for normal domain classes too, not just self-referential ones.
Nor is the mappedBy property limited to many-to-one and one-to-one associations: If you have a property called “none” on your domain class, this approach won’t work currently!
The “none” property will be treated as the reverse direction of the association or the “back reference”. Fortunately, “none” is not a common domain class property name. With Grails you define such a relationship with the hasMany setting: Grails will, by default, map this kind of relationship with a join table.
The ORM DSL allows mapping unidirectional relationships using a foreign key association instead Grails will automatically inject a property of type java. Set into the domain class based on the hasMany setting. This can be used to iterate over the collection: If you need “eager” fetching you can use the ORM DSL or specify eager fetching as part of a query The default cascading behaviour is to cascade saves and updates, but not deletes unless a belongsTo is also specified: The owning side of the relationship, in this case Authortakes responsibility for persisting the relationship and is the only side that can cascade saves across.
For example this will work and cascade saves: Grails’ Scaffolding feature does not currently support many-to-many relationship and hence you must write the code to manage the relationship yourself 6. For example, the following class creates a nicknames association that is a Set of String instances: You can alter various aspects of how the join table is mapped using the joinTable argument: In this case instead of mapping classes onto separate tables a class can be “embedded” within the current table.
Considerations At the database level Grails by default uses table-per-hierarchy mapping with a discriminator column called class so the parent class Content and its subclasses BlogEntryBook etc. 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 with the ORM DSL However, excessive use of inheritance and table-per-subclass can result in poor query performance due to the use of outer 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 Queries The 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 subclasses of Content: Set which is an unordered collection that cannot contain duplicates. In other words when you have: Sets guarantee uniqueness but not order, which may not be what you want. To have custom ordering you configure the Set as a SortedSet: SortedSet implementation is used which means you must implement java.
Comparable in your Book class: Lists of Objects 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 List: When using a Listelements must be added to the collection before being saved, otherwise Hibernate will throw an exception org.
The only change required for this is to define the collection type as a Collection: If you want a Map of objects then you can do this: The keys for the map must be strings. 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 graips 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 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: Given an 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: Grails automatically binds a Hibernate session to the currently executing request.
This lets you gom the save and delete methods as well as other GORM methods transparently. Transactional Write-Behind A useful feature of Hibernate over direct JDBC calls and even other frameworks is that when you call save or delete it does not necessarily perform any SQL operations at that point.
Hibernate batches up SQL statements and executes them as late as possible, often at the end of the request when flushing and closing the session. This is typically done for you automatically by Grails, which manages your Hibernate session. Hibernate caches database updates where possible, only actually pushing the changes when it knows that a flush is required, or when a flush is triggered programmatically.
Domain Class Usage
One common case where Hibernate will flush cached updates is when performing queries since the cached information might be included in the query results. But as long as you’re doing non-conflicting saves, updates, and deletes, they’ll be batched until the session is flushed.
This can be a significant performance boost for applications gork do a lot of database writes. Note that flushing is not the girm as committing a transaction. If your actions are performed in the context of a transaction, flushing will execute SQL updates but the database will save the changes in its transaction queue and only finalize the updates when the transaction commits. Graiks there are occasions when you 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 borm save method: This also lets you catch any exceptions, which is typically useful in highly concurrent scenarios involving optimistic locking: If that validation fails the domain instance will not be persisted to the database. By default, save will simply return null in this case, but if you would prefer it to throw an exception you can use the failOnError argument: Just remember that when you are saving domain instances that have been bound with data provided by the user, the likelihood of validation exceptions is gralls high and you won’t want those exceptions propagating to the end user.
You can find out more about the subtleties of saving data in this article – a must read! 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: If you really need to batch delete data you can use the executeUpdate method to do batch Gorn statements: The key part to remember is the belongsTo setting which controls which class “owns” a relationship. If you do not define belongsTo then no cascades will happen and you will have to graios 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: