hasMany vs having a collection of an object in grails - grails

Is there a difference between using hasMany
static hasMany = [objects:Object]
and adding a collection of object
Set objects

There is definitely a difference between using:
static hasMany = [objects:Object] and List objects
static hasMany = [objects:Object] is stored in a java set there you cannot have duplicate objects. Furthermore, the objects will not be in order of insertion.
List objects is a typical java list which will allow duplicates as well as be able to maintain order.
I believe there are more differences but I am just posting the differences I am aware of.

Related

Grails: Simple hasMany relation create more tables than necessary

Hi I have a simple problem.
My domain class is like this:
class Example {
long seq
hasMany = [example_array: ExampleData]
long count
}
class ExampleData {
String type
long description
static belongsTo = Example
static constraints = {
}
}
This results in 3 tables, like a many to many relation.
Why is this?
Thanks
The reason for the extra table is that you've modeled the relation only in one direction - an Example can access its ExampleData instances via the example_array Set that's added to your class bytecode because of the hasMany property, but an ExampleData instance has no way to reference its owning Example.
You added a belongsTo property, but only specified the class name. That's sufficient to configure ownership, cascaded deletes, etc. but doesn't provide a property in the class to access the Example instance.
If you change it to the other supported syntax it will work as you expected:
static belongsTo = [example: Example]
Here example will end up being the name of an Example property (and you can change it and/or example_array to any valid property name), which is basically the same as declaring
Example example
Now that both sides can access the other, the relationship is bidirectional and you no longer need the third table. That's because a 1-many is typically implemented using a foreign key in the child table, in this case in the table for ExampleData that points to the table for Example. That wasn't possible without a property in the class to wire up to that column, so the join table was necessary.
I believe that you have to map the BelongsTo, like this:
static belongsTo = [example:Example]
Hope it helps :)
From the definition of hasMany Grails will, by default, map this kind of relationship with a join table.That join table is the 3rd table you mentioned.No need to worry about that.
Well the one-to-many relationship is constructed by having additional table (i.e. Example_ExampleData) containing two columns each id fields from tables of the entities forming the relationship(i.e. Example and ExampleData).
The newly added table is child to parent tables – Example and ExampleData.
So in your case when you run your application the 3rd table gets created by Grails by default as your table relationship falls under the one-to-many relationship.

Grails hasOne association

What is the difference between these 2 hasOne syntax ?
class Project {
.......
............
static hasOne = Employee
// static hasOne = [employee:Employee]
}
I have noticed that the first one creates a many-to-many relationship(3 tables) but it should be many-to-one(2 tables) as in the Employee class I have:
static hasMany = [projects:Project]
The second one works fine:
static hasOne = [employee:Employee]
I am using Grails 2.2.0 and I even tried in Grails 2.0.3 but the result is same.
Thanks
I don't think that the 1st variant makes any sense at all. You could define a belongsTo back-ref without specifying a field for that, and this could be used for cascading things for example.
The case with hasOne is quite the opposite: you want to have an explicit one-to-one, which makes it logical to specify the reference explicitly:
static hasOne = [employee:Employee]
The most common case to use hasOne is when you want to have one-to-one relation, but you don't want to modify the domain class you are referencing, so that you don't have to introduce more complexity and/or migrate the old table.
To my mind, the 1st variant is useless and doesn't produce an error due to... lack of GORM developers time? ;)

Is there anyway to perform a "deep save" in Grails?

In my service I create a "root" object which has associations to many objects which in turn have associations to many more objects and so on. Once the root object is completely built and ready to be saved I would like to call save on the root object and have all associated objects all the way down be saved as well. Right now I have a recursive method called deepSave which does this. Is there a better way?
If you use belongsTo GORM automatically defines the cascading for you. This means: If A belongsTo B then A will be saved when B is saved. However, it is possible to define cascading without using belongsTo (if this does not fit to your domain model):
class Author {
static hasMany = [books: Book]
static mapping = { books cascade: 'all-delete-orphan' }
}
You should have a look at the cascade property provided by GORM. Additionaly the hibernate documentation provides more detailed information.

Setting metaClass property on domain object

Any reason not to use metaClass on domain objects? as in
domainObjectInstance.metaClass.dynamicTransientGreeting = "Hello"
Will this mess with hibernate at all?
It won't mess with Hibernate at all since it won't be seen by Hibernate. GORM only maps "real" properties to Hibernate properties.
That's why the id and version columns and the collections that are generated from hasMany declarations (e.g. the users collection generated by static hasMany = [users: User] are added to the actual bytecode using an AST. If they were added just to the MetaClass they wouldn't be seen and wouldn't be persistent.

Grails: derived fields in domain classes

Suppose I have a domain class branch which has several members:
…
static hasMany = [ members:Member ];
…
Now suppose I want to have the number of members of that branch readily available, to have it displayed in the list and view actions, so perhaps storing that information into a variable in the domain class itself would be a good idea?
…
Integer memberCount = members.size();
static constraints = {
memberCount(editable:false);
}
…
(Is this the correct syntax?) Edit: This is not the correct syntax. I cannot assess the size of the members list, as it doesn’t exist yet and grails will complain about size() not being applicable to null objects. What else could I try?
However, as memberCount is now a variable in the domain class, it is possible to assign a value to it upon creation of the Branch (which is contra-intuitive) and it will not be updated automatically once a new Member is added.
It is of course possible to reach the desired result in a different way. I could manipulate the view.gsp and list.gsp in the /Branch directory, add some additional <td>s there etc. But that does not seem very elegant to me.
Basically, I think what I am looking for is some way to tell grails that a certain variable is derived, should not be setable by the user, but update whenever necessary. Is there such way?
You can add any property you don't want persisted to the transients static list:
static transients = ['memberCount']
See this page in the manual
Also, this StackOverflow question answers the same question
Also, a better way to do derived properties may be to use the Derived Properties feature of GORM

Resources