tim*_*cus 5 grails groovy hibernate
在 Grails 中,我试图找到一个域类的实例,该实例在一对多关系中具有精确的条目。考虑这个例子:
class Author {
String name
List<Book> books
static hasMany = [books:Book]
}
class Book {
String title
static belongsTo = Author
}
Run Code Online (Sandbox Code Playgroud)
我的数据库然后显示如下:
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
----------------------------------------
Run Code Online (Sandbox Code Playgroud)
我希望能够做的是对作者使用动态查找器。我正在寻找 hasMany 关系的精确匹配,以匹配此行为:
Author.findByBooks([1]) => null
Author.findByBooks([1, 2]) => author(id:1)
Author.findByBooks([1, 3]) => null
Author.findByBooks([3, 4]) => author(id:2)
Run Code Online (Sandbox Code Playgroud)
尝试这样做会导致丑陋的 Hibernate 错误:
hibernate.util.JDBCExceptionReporter No value specified for parameter 1.
Run Code Online (Sandbox Code Playgroud)
有没有人让动态查找器处理域类的 hasMany 关系?获得所需行为的最“Grails-y”解决方案是什么?
从您的域模型中不清楚是否Book属于作者。如果是这样,您应该将该事实添加到您的域模型中并像 Tom Metz 所说的那样进行查询。
让我把这件事搞清楚。您想要查找撰写标题(或 ID)为“Book 1”和“Book 2”的书籍的作者。要进行检查,您必须连接 Book 表两次,以便将连接一中的书名与“Book 1”进行比较,以及将连接二中的书名与“Book2”进行比较。
人们可以假设以下测试应该有效:
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")
}
Run Code Online (Sandbox Code Playgroud)
但事实证明,结果集是空的。Grails 将每一本书闭包中的语句合并到一个连接中。
这是查询结果:
select this_.id as id1_1_, this_.version as version1_1_, this_.name as name1_1_, books3_.author_books_id as author1_1_, books_alia1_.id as book2_, books3_.books_idx as books3_, books_alia1_.id as id0_0_, books_alia1_.version as version0_0_, books_alia1_.title as title0_0_ from 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 where (books_alia1_.title=?) and (books_alia1_.title=?)
Run Code Online (Sandbox Code Playgroud)
ASFAIK 这不能使用 grails criteria api 来实现。但你可以使用 hql 代替。以下测试有效:
void testAuthorHql() {
def result = Author.executeQuery("select a from Author a join a.books bookOne join a.books bookTwo where bookOne.title=? and bookTwo.title=?", ['Book 1', 'Book 3'])
assert 1 == result.size()
assertTrue(result.first().name == "Ted Jones")
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4778 次 |
| 最近记录: |