I'm trying to do a many-to-many relationship on Grails 1.3.4 and I'm getting this exception:
Caused by: org.codehaus.groovy.grails.exceptions.GrailsDomainException: No owner defined between domain
classes [class gblog.Post] and [class gblog.Comentario] in a many-to-many relationship.
Example: static belongsTo = gblog.Comentario
The code for Comentario is:
package gblog
class Comentario {
static constraints = {
}
String conteudo
Date data
static belongsTo = [post:Post, autor:Usuario]
static hasMany = [posts:Post]
}
The code for Post is:
package gblog
class Post {
static constraints = {
}
String titulo
String conteudo
String palavrasChave
Date data
static belongsTo = [categoria:Categoria, autor:Usuario]
static hasMany = [comentarios:Comentario]
}
Thanks everybody!
I think Grails is getting confused here:
static belongsTo = [post:Post, autor: Usuario]
static hasMany = [posts:Post]
You might want to diagram how all of the classes are interacting, because I'm thinking that this is a little off.
Related
Good day to all. I am very new in using grails and I have followed several tutorials for beginners using grails until I come up in creating domain relationships. However, I got stuck with this problem right now. I have 3 domain classes namely, todo, category and user. And as I defined their relationships, it returns me an error saying unable to resolve class. Please see my codes below. Please help. Thank you so much.
Todo.groovy Class
package todoScaff
class Todo {
String name
String note
Date createDate
Date dueDate
Date completedDate
String priority
String status
User owner
Category category
static belongsTo = [User, Category]
static constraints = {
name(blank:false)
createDate()
priority()
status()
note(maxsize:1000, nullable:true)
completedDate(nullable:true)
dueDate(nullable:true)
}
String toString() {
name
}
}
Category.groovy Class
package categoryScaff
class Category {
String name
String description
User user
static belongsTo = User
static hasMany = [todos: Todo]
static constraints = {
name(blank:false)
}
String toString(){
name
}
}
User.groovy Class
package userScaff
class User {
String userName
String fname
String lname
static hasMany = [todos: Todo, categories: Category]
static constraints = {
userName(blank:false, unique:true)
fname(blank:false)
lname(blank:false)
}
String toString(){
"$lname, $fname"
}
}
Since you've placed your domain classes in different packages, you must import the classes at the head of the file.
package categoryScaff
import todoScaff.Todo
import userScaff.User
class Category {
The same needs to happen in your other domain classes that reference classes outside the current package.
What is the difference between
static belongsTo [author:Author]
and
static belongsTo = Author
Lets consider two domain class.
Class Author{
String name
}
Class Books{
String name
static belongsTo = Author
}
When static belongsTo = Author is kept in Books domain, it have no effects on db. However, static belongsTo = [author : Author] creates a backreference to Author class and also there is author_id column in db. So, what actually using static belongsTo = Author alone does.
This is expalined in grails docs(http://grails.github.io/grails-doc/latest/ref/Domain%20Classes/belongsTo.html).
Also, what is the difference between using following two :
Class Books{
String name
static belongsTo = [author : Author]
}
Class Books{
String name
Author author
}
static belongsTo = [author : Author] is used only for cascading purposes, Is it true or does it have different use cases.
Can anyone explain these in detail without relating it to hasOne or hasMany. Thanks in advance.
Using belongsTo without a back-reference is necessary for many-to-many associations. For example, lets assume you have the following domain classes:
class Book {
String name
Author author
static hasMany = [categories: Category]
}
class Category {
String name
static hasMany = [books: Book]
}
If you try to use them as-is you'd get an exception like this:
No owner defined between domain classes [class Book] and [class Category] in a many-to-many relationship. Example: static belongsTo = Category
The solution is to make one of the domain classes the owner of the many-to-many association. Using my example, I think it makes more sense to make the Category the owner. However, a back-reference would not work because there could be multiple Categorys. So, this is where a belongsTo without a back-reference comes in:
class Book {
String name
Author author
static hasMany = [categories: Category]
static belongsTo = Category
}
If you use static belongsTo = [author: Author] then a property named author of type Author is added to the class as a back reference. With static belongsTo = Author that does not happen.
Currently i'm getting the following error :
No owner defined between domain classes [class mp.ra.Classgroup] and [class mp.ra.Event] in a many-to-many relationship.
The domain classes are set up as followed,
The event class:
class Event {
static hasMany = [classgroups:Classgroup]
static belongsTo = [eventgroup:Eventgroup,classgroup:Classgroup]
static constraints = {
eventgroup nullable:true
}
And the Classgroup
class Classgroup {
static hasMany = [courses:Course,events:Event]
static constraints = {
courses nullable:true
}
An Event can have multiple classgroups and a classgroup can have multiple events.
I use the belongs to property so i don't see why i'm getting this error.
EDIT: I changed The Event class and the error is gone , i dont know if this is a good solution
class Event {
Eventgroup eventgroup
static hasMany = [classgroups:Classgroup]
static belongsTo = [Eventgroup, Classgroup]
static constraints = {
eventgroup nullable:true
}
In Grails many-to-many mapping we should define an owner class between both of the associated classes.
As earlier you defined :
belongsTo = [eventgroup:Eventgroup,classgroup:Classgroup]
with this GORM tried to create a column with classgroup name under Event table, but for many-to-many association with classgroup, database should suppose to have third table to have multiple records for many-to-many associations between Event and Classgroup. So was giving such error.
Hence later when you mention :
belongsTo = [Eventgroup, Classgroup]
it worked as it just got owner information.
So here Classgroup would be the owner of association, as Event belongsTo Classgroup.
Hope this helps. Thanks.
I'm trying to use the commandObject to validade my data when I submit my form. Can I validate a hasMany relation in commandObject. My cenario is something like this.
Tow simple classes whith hasMany relationship:
class Book{
String nameBook
}
class Author{
String nameAuthor
static hasMany = [books:Book]
}
Simple commandObject with hasMany that i want to validate when submit form.
#grails.validation.Validateable
class MyValidateCommand{
String nameAuthor
static hasMany = [books:Book]
static constraints = {
nameAuthor nullable:false
books nullable:false
}
}
Ps: I know that this commandObject is wrong, it don't compile. But can I do something like this ???
hasMany in GORM is used for association in Domain objects. In case of command objects it will be a lucid approach to have different command objects for each domain (for example: AuthorCommand and BookCommand) and the command object would look like:
import org.apache.commons.collections.list.LazyList
import org.apache.commons.collections.functors.InstantiateFactory
//Dont need this annotation if command object
//is in the same location as the controller
//By default its validateable
#grails.validation.Validateable
class AuthorCommand{
String nameAuthor
//static hasMany = [books:Book]
//Lazily initialized list for BookCommand
//which will be efficient based on the form submission.
List<BookCommand> books =
LazyList.decorate(new ArrayList(),
new InstantiateFactory(BookCommand.class))
static constraints = {
nameAuthor nullable:false
books nullable:false
//Let BookCommand do its validation,
//although you can have a custom validator to do some
//validation here.
}
}
Not sure why don't you can try like(normal hibernate hasMany declaration)
class MyValidateCommand{
String nameAuthor
Set<Book> books= new HashSet<Book>();
static constraints = {
nameAuthor nullable:false
books nullable:false
}
}
I have three classes in my grails project. What is the proper grails domain definition
Class A {
List<Resource> xResources
List<Resource> yResources
hasMany = [ xResources: Resource, yResources: Resource]
}
Class B {
List<Resource> zResources
hasMany = [ zResources: Resource]
}
Class Resource {
String title
.....
..
belongsTo = [A, B]
}
The above definition fails because i have not mentioned the mappedBy in Class A. How that can be avoided. I want the Resource class to be generic.
I don't want to restrict the Resource class only to the two classes, but i should allow it extend it to other. I also need to get the source reference from a Resource object. What should be proper GORM definition for this scenario.?
I see 3 major issues in your code:
The properties xResources, yResources, zResources is double defined. Just remove the duplicate List<Resource> ... definition.
hasMany and belongsTo should have a static key word before it.
I'm not sure belongsTo can point to more than one class. If not, just remove it.
Please follow the below code
Class A {
static hasMany = [ xResources: Resource, yResources: Resource]
}
Class B {
static hasMany = [ zResources: Resource]
}
Class Resource {
String title
.....
..
static belongsTo = [a:A, b:B]
}