class Book {
String title
Date releaseDate
String ISBN
static belongsTo = [person:Person] // it makes relationship bi-directional regarding the grails-docs
}
class Person {
Book book; // it will create person.book_id
String name
Integer age
Date lastVisit
static constraints = {
book unique: true // "one-to-one". Without that = "Many-to-one".
}
}
有一个测试,测试它是否是真正的双向。据我所知。
public void testBidirectional() {
def person = new Person(name:"person_c1", age: 99, lastVisit: new Date())
def book = new Book(
title:"somebook_c1",
ISBN: "somebook_c1",
releaseDate: new Date()
)
person.setBook (book)
assertNotNull(person.save())
def bookId = person.getBook().id
Book thatBook = Book.get(bookId)
assertNotNull(thatBook.person) // NULL !!!
}
所以,我用书保存一个人,然后我通过id从db获得 book 。然后从那本书我试着找回哪本书应该引用的人(因为它应该是双向的,对吧?)。最终我得到 null 而不是人的实例。
任务是: 如何使测试有效?
答案 0 :(得分:1)
我找到了解决方案如何让它工作,但仍然无法理解为什么没有'刷新'它不起作用,见下文:
public void testBidirectional() {
def person = new Person(name:"person_c1", age: 99, lastVisit: new Date())
def book = new Book(
title:"somebook_c1",
ISBN: "somebook_c1",
releaseDate: new Date()
)
person.setBook (book)
def p = person.save()
assertNotNull p
person.refresh() //load the object again from the database so all the changes made to object will be reverted
//person = Person.get(p.id) // BUT this also gets the object from db ...?
def bookId = person.getBook().id
assertNotNull bookId
def thatBook = Book.get(bookId)
assertNotNull(thatBook.person)
}
所以,在这里你可以看到我使用'refresh'来使它工作,但是为什么它没有'刷新'但在'刷新'之后使用以下行不起作用 - 这个:
person = Person.get(p.id) // BUT this also gets the object from db ...?
如果我只想通过id从获取数据库中的对象,那么它将是没有双向的?
答案 1 :(得分:1)
您的问题可能是由Hibernate的工作方式引起的。 Grails在引擎盖下使用了Hibernate。
即使您调用“save”,对象 person 也可能(并且通常)不会保存在数据库中。那是因为Hibernate被编程为优化查询,所以它经常等待在Hibernate会话结束时执行所有查询。
这意味着如果您不调用“刷新”,则书人关系(person.setBook)仍在内存中,但不会保存在数据库中。因此,您无法从book.person
获取book
。
要强制执行保存,您可以像上一个答案一样使用“刷新”,或使用flush:true。
我仍然没有尝试过,但很可能会产生以下结果:
person.save(flush:true)