A one-to-one relationship is the simplest kind, and was defined trivially using a property of the type of another domain CL The. Consider this example:
Example A
Class Face {
Nose Nose
}
class Nose {
}
In the We have the unidirectional many-to-one relationship from the face to Nose. To make it a true one-to-one your should make nose unique:
Class Face {
Nose Nose
static constraints = {
Nose unique:true
}
}
class Nose {
}
Relationship bidirectional define the other side as follows:
Example B
Class Face {
Nose Nose
}
class Nose {
static belongsto = [Face:face]
}
In this box we use the Belongsto setting to say that Nose "belongs to" face. The result of this is, we can create a face and save it and the database updates/inserts'll be cascaded down to Nose :
New Face (Nose:new nose ()). Save ()
The example above would save both face and nose. Note that the inverse are not true and would result in an error due to a transient face:
New Nose (Face:new Face ()). Save ()//would cause an error
Another important implication of Belongsto is so if you delete a face instance the Nose would be deleted too:
def f = face.get (1)
f.delete ()//both face and Nose deleted
In the previous example the foreign key associated the face with the Nose are stored in the parent as column called nose_id . If you want the foreign key to being stored in the child you need a HasOne association:
Example C
Class Face {
static hasOne = [Nose:nose]
}
class Nose {face face
}
String name} class book {string title}
In the We have a unidirectional one-to-many. Grails would, 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 would automatically inject a property of type Java.util.Set to the domain class based on the Hasmany setting. This can is used to iterate over the collection:
def a = Author.get (1)
A.books.each {println It.title}
The default fetch strategy used by Grails are "lazy", which means that the collection would be lazily initialized. This can leads to the n+1 problem if is not careful.
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:
Class Author {
static hasmany = [Books:book]
String name} class Book {static Belongsto = [Author:author] string title}
If you have both properties of the of the same type on the many side of a one-to-many you had to use Mappedby to specify which th E Collection is mapped:
Class Airport {
static hasmany = [Flights:flight]
static Mappedby = [flights: ' Departureairport ']
}
Class Flight {
Airport departureairport
Airport Destinationairport
}
This is also true if you have multiple collections, which map to different properties on the many side:
Class Airport {
static hasmany = [Outboundflights:flight, inboundflights:flight]
static Mappedby = [ Outboundflights: "Departureairport", Inboundflights: "Destinationairport"]
}
class Flight {
Airport Departureairport
Airport Destinationairport
}
Grails maps a many-to-many using a join table at the database level. The owning side of the relationship, in this case Author, takes responsibility for persisting the relationship and is the Only side that can cascade saves across.
For example this would work and Cascade saves:
new Author (name: "Stephen King"). Addtobooks ( New book (title: "The Stand"). Addtobooks (title: "The Shining"). Save ()
However the below would only Save the book and not the authors!
new book (Name: "Groovy in Action"). Addtoauthors (New Author (name: "Dierk Koenig")). Addtoauthors ( New Author (name: "Guillaume laforge")). Save ()
This was the expected behaviour as, just like Hibernate, only on E side of a many-to-many can take responsibility for managing the relationship.