哪里是双向的? grails one-to-one,双向测试(续)

时间:2010-12-25 18:09:30

标签: grails gorm


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 而不是的实例。

任务是: 如何使测试有效?

2 个答案:

答案 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)