где двунаправленный? Grails один к одному, тестирование двунаправленное (продолжение) - PullRequest
1 голос
/ 25 декабря 2010

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 !!!
  }

Итак, я спасаю человека с книгой , а затем я получил эту книгу из БД.по идентификаторуЗатем из этой книги я пытаюсь вернуть человека , на какую книгу следует ссылаться (потому что она должна быть двунаправленной, верно?).В конце концов я получил null вместо экземпляра person .

Задание: как заставить этот тест работать?

Ответы [ 2 ]

1 голос
/ 27 декабря 2010

Ваша проблема, вероятно, вызвана тем, как работает Hibernate.Grails использовал Hibernate под капотом.

Даже когда вы вызываете «save», объект person может (и обычно) не сохраняться в базе данных. Это потому, что Hibernateзапрограммирован на оптимизацию запроса, поэтому он часто ожидает выполнения всего запроса в конце сеанса Hibernate.

Это означает, что если вы не вызываете «обновить», отношение книга-человек (person.setBook)все еще в памяти, но не сохраняется в базе данных.Следовательно, вы не можете получить book.person из book.

. Для принудительного сохранения вы можете использовать «обновить», как в предыдущем ответе, или использовать flush: true.

Iвсе еще не пытайтесь, но очень вероятно, что вы получите желаемый результат с:

person.save(flush:true)
1 голос
/ 26 декабря 2010

Я нашел решение, как заставить его работать, но все еще не могу понять, почему он не работает без «обновления», см. Ниже:



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», чтобы заставить его работать, но почему он не работает без «refresh», а со следующей строкой после «refresh» - вот эта: person = Person.get(p.id) // BUT this also gets the object from db ...?

Если я просто хочу получить объект из базы данных по идентификатору, то это будет без двунаправленного?

...