Is it possible to have an index on a hasMany property?
Class Author(){
static hasMany = [books: Book]
static mapping = {
books index:'book_id'
}
}
You can use like this.
Class Author(){
static hasMany = [books: Book]
List books // Generates column `book_idx` in table for Book.
static mapping = {
books indexColumn: [name: "book", type: Integer]
}
}
Related
I have a simple relationship between two tables as below:
class Book {
String title
static hasMany = [authors: Author]
}
class Author {
String Name
}
I have a requirement that while Book can have many authors, one Author can only have one Book. Authors can exist independent of Books.
With what constraints can I make sure that one Author can have one Book?
class Book {
String title
static hasMany = [authors: Author]
}
class Author {
String Name
Book book // this will be the belongTo relationship that you need
static constraints = {
book nullable:true
}
}
I am having a problem setting up a List as a hasMany relationship to a belongsTo withing an extended class.
With a new Grails 2.4.4 app I have these 3 Domains:
An Author class having many books.
class Author {
List books
static hasMany = [books: Book]
}
A Book class which extends Content
class Book extends Content {
String foo
}
And Content, which has a number of common properties.
class Content {
String title
static belongsTo = [author: Author]
static constraints = {
sort: 'title'
}
}
When running this application I get the following exception:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: test.relationships.Book column: author_id (should be mapped with insert="false" update="false")
I only get this exception when I make books a List.
I think the problem is probably something to do with the fact you're saying that Author has many Books, but the superclass of Book, Content, belongs to an Authur.
What happens if you change your Content and Book classes to this:
class Content {
String title
static constraints = {
sort: 'title'
}
}
class Book extends Content {
static belongsTo = [author: Author]
String foo
}
or, alternatively, change your Author class to this:
class Author {
List books
static hasMany = [contents: Content]
}
I am trying to have a List of String that works in MySql in a Grails domain class.
I have tried the following:
class Catalogue {
List books
String book
static hasMany = [books: book]
}
and
class Catalogue {
List books
}
and
class Catalogue {
String[] books
}
and
class Catalogue {
ArrayList<String> books = new ArrayList<String>()
}
The last three compiles but the entry is not present in MySQL.
There is no table, or column to represent this data in MySQL and I have tried populating the array with data. Still nothing.
Any ideas?
You can achieve this by using hasMany. Furthermore you need to define books as a List since without it you would get a simple Set that does not allow any duplicates.
class Catalogue {
static hasMany = [books: String]
List books
}
Create a domain Book class:
class Book {
String title
String isbn
...
String toString(){
return "${title}"
}
}
and modify your Catalogue as
class Catalogue{
String name
....
static hasMany = [books: Book]
//etc etc
}
I am working with legacy database and have a many-to-many association with a join-table that I have resolved to a large extent as the mappings are working fine. But there is an additional column and in case of Book, Author model lets say that the nm_author_books contain a field called 'royalty'. Question is how do I access this field from any direction?
class Book {
String title
static belongsTo = Author
static hasMany = [authors: Author]
static mapping = { authors joinTable: [name: "mm_author_books", key: 'mm_book_id' ] }
}
class Author {
String name
static hasMany = [books: Book]
static mapping = { books joinTable: [name: "mm_author_books", key: 'mm_author_id'] }
}
If the nm_author_book table has [nm_book_id, nm_author_id, royalty] what is the way to access the royalty?
The basic idea is change from 1 many-to-many to 2 many-to-one: a Book has many BookAuthorDetail and a Author has many BookAuthorDetail
class Book {
String title
static hasMany = [details: BookAuthorDetail]
}
class Author {
String name
static hasMany = [details: BookAuthorDetail]
}
class BookAuthorDetail {
String royalty
static belongsTo = [book: Book, author: Author]
}
to access royalty by BookAuthorDetail, you can do: BookAuthorDetail.findAllByBookAndAuthor(bookInstance, authorInstance)
You could make a domain object that models that join table so instead of changing the mapping for Book and Author you have them point to the AuthorBookRoyalty domain.
Class AuthorBookRoyalty {
Author author
Book book
Long royalty
}
class Book {
String title
static belongsTo =Author
Static hasMany[authors: AuthorBookRoyalty]
}
Do similar for Author and you can now deal with the royalties. You may need to adjust the mapping on the join table to make it map to your current database.
Another option is to access these additional fields directly from the mapped entity of the join table:
class Book {
String title
static belongsTo = Author
static hasMany = [authors: Author]
static mapping = { authors joinTable: [name: "mm_author_books", key: 'mm_book_id' ] }
}
class Author {
String name
static hasMany = [books: Book]
static mapping = { books joinTable: [name: "mm_author_books", key: 'mm_author_id'] }
}
class AuthorBooks {
Author author
Book book
Long royalty
static mapping = {
table name: "mm_author_books"
author column: "mm_author_id"
book column: "mm_book_id"
}
}
You can access royalty with the following code, for instance:
AuthorBooks.findAllByBookAndAuthor(bookInstance, authorInstance)*.royalty
Say you have two domain classes: Authors and Books. Authors can have many Books, but a Book can only have one Author.
class Author {
static hasMany = [Book]
}
class Book {
static belongsTo = Author
}
How do you query is book's author?
This doesn't seem to work:
def book = Book.get(1)
book.author
change your code to:
class Author {
static hasMany = [book:Book]
}
class Book {
static belongsTo = [author:Author]
}
then this should work:
def book = Book.get(1)
book.author