hibernate - Matching hasMany children with Grails dynamic finders -
in grails, i'm attempting find instance of domain class has exact entries in one-to-many relationship. consider example:
class author { string name list<book> books static hasmany = [books:book] } class book { string title static belongsto = author }
my database appears such:
author book ------------------------- ------------------------ | id | name | | id | title | |----|------------------| ------------------------ | 1 | john steinbeck | | 1 | grapes of wrath | | 2 | michael crichton | | 2 | east of eden | ------------------------- | 3 | timeline | | 4 | jurassic park | ------------------------ author_book ---------------------------------------- | author_books_id | book_id | book_idx | ---------------------------------------- | 1 | 1 | 0 | // john steinbeck - grapes of wrath | 1 | 2 | 1 | // john steinbeck - east of eden | 2 | 3 | 0 | // michael crichton - timeline | 2 | 4 | 1 | // michael crichton - jurassic park ----------------------------------------
what i'd able use dynamic finder on author. i'm searching exact match on hasmany relation, match behavior:
author.findbybooks([1]) => null author.findbybooks([1, 2]) => author(id:1) author.findbybooks([1, 3]) => null author.findbybooks([3, 4]) => author(id:2)
attempting results in ugly hibernate error:
hibernate.util.jdbcexceptionreporter no value specified parameter 1.
has had dynamic finders work hasmany relationships of domain classes? 'grails-y' solution desired behavior?
its not clear domain model if book
belongs author. if so, should add fact domain model , query tom metz said.
let me right. want find author[s] have writen books title (or id) i.e. 'book 1' , 'book 2'. make check work have join book table 2 times in order compare book title join 1 'book 1' , book title join 2 'book2'.
one assume following test should work:
void setup() { def author = new author(name: "ted jones").save(flush: true) def author2 = new author(name: "beth peters").save(flush: true) def author3 = new author(name: "foo bar").save(flush: true) def book1 = new book(title: 'book 1').save(flush: true) def book2 = new book(title: 'book 2').save(flush: true) def book3 = new book(title: 'book 3').save(flush: true) def book4 = new book(title: 'book 4').save(flush: true) author.addtobooks(book1) author.addtobooks(book3) author2.addtobooks(book2) author2.addtobooks(book4) author3.addtobooks(book1) author3.addtobooks(book2) } void testauthorcrit() { def result = author.withcriteria() { books { eq("title", "book 1") } books { eq("title", "book 3") } } assert 1 == result.size() asserttrue(result.first().name == "ted jones") }
but turns out, result set empty. grails merges statements in each books closure 1 join.
this resulting query:
select this_.id id1_1_, this_.version version1_1_, this_.name name1_1_, books3_.author_books_id author1_1_, books_alia1_.id book2_, books3_.books_idx books3_, books_alia1_.id id0_0_, books_alia1_.version version0_0_, books_alia1_.title title0_0_ author this_ inner join author_book books3_ on this_.id=books3_.author_books_id inner join book books_alia1_ on books3_.book_id=books_alia1_.id (books_alia1_.title=?) , (books_alia1_.title=?)
asfaik cannot archieved using grails criteria api. can use hql instead. following test works:
void testauthorhql() { def result = author.executequery("select author join a.books bookone join a.books booktwo bookone.title=? , booktwo.title=?", ['book 1', 'book 3']) assert 1 == result.size() asserttrue(result.first().name == "ted jones") }
Comments
Post a Comment