Grails hasOne vs. belongsTo - grails

To create one-to-one relationships in Grails I can do:
class Person {
static hasOne = [address: Address]
}
In this case the Address table has the key to its person. I could also do:
class Address {
static belongsTo = [person: Person]
}
This gives the same result.
What is the difference between my two samples using hasOne and belongsTo?

hasOne indicates that there is a bi-directional one-to-one relationship where the child table has the parent's foreign key, as in your example.
belongsTo is used to control cascades by indicating that the class belongs to the specified class. In your example, deleting a given Person would cascade the delete to any associated Addresses.

Related

Grails 3 hasOne nullability issue

While migrating an existing app from Grails 2.5 to 3.1, I ran into an odd issue with a bi-directional one-to-one relationship.
Imagine a simple model with a User and Employee objects. A User represents a generic user account. Not all users are Employees but all Employees are Users. Moreover Employees have references to managers, supervisors, etc (also User instances). User is the owning side of the relationship.
class User {
Employee employee
static mappedBy = [employee: "user"]
static hasOne = [employee: Employee]
static constraints = {
employee(nullable:true)
}
}
class Employee {
User user // represents employee's own account, a bi-directional one-to-one
User supervisor // represents a supervisor
static belongsTo = [user: User]
static constraints = {
user(unique:true)
supervisor(nullable:true)
}
}
The trouble after upgrading to Grails 3 is that in the create mode, this results in supervisor_id column of employee table being generated as NOT NULL, whereas in Grails 2 it was nullable as expected (with only user_id being NOT NULL).
I tested this with Grails 3.1.12 and 3.2.0, getting the same behavior with both. Am I doing anything stupid in my domain class declarations? I've tried multiple mappings to achieve the same behavior as in Grails 2.5 without luck. In some cases I'm even getting a foreign key on both sides of the relationship...
I don't know why your code was working with previous version of Grails, but it is wrong.
When you use hasMany and belongsTo, it is not necessary to define other property in the child object, and you don't need also to use the mappedBy property on the parent, and the same with the parent (property employee at User)
Grails doesn't need anything else to know which is the bidirectional property on both classes, and the constraint user(unique : true) neither.
So your classes should look like this:
class User {
static hasOne = [employee: Employee]
static constraints = {
employee(nullable: true)
}
}
class Employee {
User supervisor // represents a supervisor
static belongsTo = [user: User]
static constraints = {
supervisor(nullable:true)
}
}
It could be nice to know how is your DB structure. But in this way all foreign keys are stored in the employee table. But of course you could navigate from both entities. If you have different structure you could map your current database with this model. See this
employee.user
user.employee

OneToMany association in grails domain classes

I want one to many association between the Person and Address domain class which will be more like :
create table person (id bigint),
version bigint not null,
primary key (id))
create table address (id bigint),
person_id bigint not null,
primary key (id))
I tried to establish oneToMany Relation between these two tables so that one person can have n number of addresses.
class Person{
static hasMany = [
addresses: Address
]
}
class Address{
Address address
}
This is how I think it should work, i tried serveral other option, but none worked as wanted. Either I get an crosstable or an error when starting the application.
Thanks for help
You need to do establish one-to-many relationship between the Domain class Person & Address as given below-
Person Domain class
class Person{
static hasMany = [addresses: Address]
}
Address Domain class
class Address{
static belongsTo = [person : Person]
}
Please go through the grails documentation for gorm to understand the
domain class relationships in depth.

How to use mappedBy correctly in one to many relation

I am new to grails. I have a problem with one to many relation with my two classes. I have two classes Person and Child as follows
class Child
{
String name
String grade
Person father
Person mother
Person guide
}
and Person class looks like
class Person
{
String name
hasMany[child: Child]
}
How do I use mappedBy here correctly
I have looked here . The example given in that link shows mappedBy when the many side has two properties of parent class. how do I use here mappedBy correctly? What difference does it make in the database level? Please help..
You can do it like this
class Person {
static hasMany = [childs: Child]
static mappedBy = [childs:'father'] //or whichever parent you want to use
}
As you have only one collection in Person domain, you can map it to just one parent. If you want to map childs for all three parents, you will need three collections in the Person

How does one mix 'Reference' and 'No Reference' belongTo relationships in one Domain Class?

In Grails belongsTo allows one domain class to establish a cascading relationship with another domain class. There are two styles of relationships when using belongsTo: Reference and No Reference. Reference creates a property on the owned object while No Reference merely establishes an invisible GORM relationship.
Example parent domain-class:
class Car {
Engine engine
}
belongsTo without Reference property:
class Engine {
static belongsTo = Car
}
belongsTo with Reference property:
class Engine {
static belongsTo = [car:Car]
}
Not to hard right, however the trouble for me starts when we start using multiple belongsTo references:
belongsTo with multiple back references:
class Engine {
static belongsTo = [car:Car, user:User]
}
multiple belongsTo relationships without property references:
class Engine {
static belongsTo = [Car, User]
}
Here's the problem, how do I mix the two above styles?
Say I want a property reference for the User but not for the Car, how would I write that belongsTo call?
Any information on how to mix No Reference relationship links with Reference property in a single domain class would help.
Links:
Using Grails Object Relational Mapping (GORM)
belongsTo - grails.org
This question reposted by me on the official Grails forum
class Engine {
User user
static belongsTo = [Car, User]
}
That said, I always use the map (reference) syntax over the list (no reference) syntax because I like mine to be bi-directional.

Deleting m-to-m is also trying to cascade delete a one-2-one

I have the following Domains
class Committee {
String name
BoardCommitteeType boardCommitteeType
Date dateCreated
Date lastUpdated
User createdBy
User modifiedBy
static belongsTo = [
board: Board,
]
static hasMany = [
members: User
]
}
class User {
static hasMany = [
committees: Committee,
]
static belongsTo = [
Board, Committee
]
}
The problem is that when I attempt to do a board.removeFromCommittees(committee) I'm getting the following exception:
deleted object would be re-saved by cascade (remove deleted object from associations): [com.wbr.highbar.User#1];
I understand what that means. What I don't understand is why I am getting it. The other interesting bit is that if I make creatdBy and modifiedBy in the Committee instance null, the delete works just fine. That's why I am thinking that GORM is trying cascade the one-2-one. My theory is that is has something to do with the fact User belongsTo a Committee. But I don't know how to fix the problem.
The cascading delete is effected by the belongsTo relationships between your domain classes.
Since Committee belongsTo Board, when a Board gets deleted, the delete cascades to the Committee. Since User belongsTo Committee, when a Committee gets deleted, the delete cascades to the User.
The solution to your problem is to remove the User belongsTo Committee relationship.
Notes on your domain model as a whole:
You have a lot of many-to-many relationships. They're not necessarily wrong, but they might be overcomplicating things. You could probably get away with just using:
class Committee {
static hasMany = [boards: Board, users: User]
}
class Board {
static hasMany = [users: User]
static belongsTo = Committee // this is the only belongsTo you need, since if a
// committee is dissolved, presumably the board
// will be dissolved as well (unless you have
// cross-committee boards)
}
class User {
// doesn't define any relationships,
// let the Committee/Board domains handle everything
// also, this is presuming that users are at a higher level than committees, i.e.
// a user could belong to multiple committees
}

Resources