What is the ideal Grails class domain for this tree structure - grails

I'm developing a website that need categories with sub categories.
My current domain class is:
package com.abc
class Category {
String title
String description
Category parent
static hasMany = [children: Category, listing: Listing]
static constraints = {
title blank: false
description blank: true
}
}
But it gives me an error:
Property [children] in class [class com.abc.Category] is a
bidirectional one-to-many with two possible properties on the inverse
side. Either name one of the properties on other side of the
relationship [category] or use the 'mappedBy' static to define the
property that the relationship is mapped with. Example: static
mappedBy = [children:'myprop']

I would use only Category parent. We can always get children by Category.findAllByParent. This is also the easiest solution to use later on in tree creation.

Related

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

Modeling a many-to-one tree in grails

I'm attempting to model an organizational tree in grails. What I have works, but I have a couple of questions about it.
Here's my 'Organization' class:
class Organization {
String title
Organization parentOrg
static hasMany = [ childOrg: Organization ]
static mappedBy = [
childOrg: 'parentOrg',
parentOrg: 'childOrg'
]
static constraints = {
parentOrg nullable: true
}
}
Now, when I create a new 'Organization' like this:
def newOrg = new Organization(
title: 'New Organization',
parentOrg: oldOrg).save()
Everything works well, and the relationship to the parent seems modeled correctly.
But if I try to call something like oldOrg.childOrg.each I will get no results unless I have also called oldOrg.addToChildOrg(newOrg).
Furthermore, when I check the tables that are generated, the only reference to this relation is the parent_org_id column on the Organization table.
Now, I realize that this is all that is necessary to also determine the childOrg relations, but I don't notice ANY change in the database from before I call oldOrg.addToChildOrg(newOrg) to after!
So where is this relation getting stored when I call addToChildOrg when I don't see anything change in the database?
Also, how can I have this relation setup to automatically create the childOrg relation when I add the parentOrg? I don't think I should have to call addToChildOrg when I'm adding the parentOrg. It should be implied.
Thanks!
Use a hasOne association to store the foreign key reference in a bidirectional one-to-one.
Since you don't want to add the relationship from other side each time so you can make a setter to ease your work, like-
setParentOrg(parentInstance){
this.parentOrg = parentInstance
parentInstance.childOrg = this
}
Now when you do organisationInstance.parentOrg = parentInstance, the setter gets invoked for you, and the relationship is setup the way you want.
if I'm correct you're missing belongsTo definition, because you need to define that every instance of Organization is owned by its parentOrg instance.
try this class declaration:
class Organization {
String title
Organization parentOrg
static belongsTo = [parentOrg: Organization]
static hasMany = [ childOrg: Organization ]
static mappedBy = [ childOrg: 'parentOrg']
static constraints = {
parentOrg nullable: true
}
}

Child class object can not delete

I have some domain class Incident,Problem, Category, Impact, Urgency etc.
Class Incident
{
Category category
String subject
Impact impact
}
Class Problem
{
Urgency urgency
Category category
String title
}
Class Category
{
String categoryName
String description
}
now, some rows are inserted into this class. now if I am deleting category it throws error like 'grails cannot delete or update a parent row'..
so what I have to do for deleting?
The problem is - you have reference to Category in Incident and Problem classes, so database tables for those classes will have Foreign key on category table, so you can not delete a category untill you either remove those incidents/problems or update those incidents problems and set category to null (you will have to make them as nullable in domain constraints)
So either you do
Problem.executeUpdate('update Problem p set category = null where category = ?', [category])
Same for incidents
Or you can model your domain classes using belongsTo and hasMany and grails will handle every thing automatically
Some thing like
class Problem {
static belongsTo = [category:Category]
}
class Category {
static hasMany = [
problems: Problem
]
static mappings = {
problems cascade: "all-delete-orphan"
}
}
I would prefer to manage relationships using belongsTo, hasMany, hasOne rather then just using references, it expresses the model better.
It depends on your domain model as well, in your business can problems, incidents exist without a category ! or they must belong to some category. If your answer is first option, your dont want to cascade delete, but update those incidents/problems with null category, if your answer is second option - you needs cascade all-delete-orphan
How your Category looks like, is it belongsTo Incident domain class,if category belongs to some domain class you can not delete it.
Ref : See here

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.

Grails domain class relationship to itself

I need a way to be able to have a domain class to have many of itself. In other words, there is a parent and child relationship. The table I'm working on has data and then a column called "parent_id". If any item has the parent_id set, it is a child of that element.
Is there any way in Grails to tell hasMany which field to look at for a reference?
This is an example of what you are looking for (it's a snippet code I am running and it generates column parent_id). I don't think you need SortedSet:
class NavMenu implements Comparable {
String category
int rank = 0
String title
Boolean active = false
//NavMenu parent
SortedSet subItems
static hasMany = [subItems: NavMenu]
static belongsTo = [parent: NavMenu]
}
Furthermore, you can give name to the hasMany clause using the Mapping DSL, which is explained at http://grails.org/GORM+-+Mapping+DSL

Resources