保存后,Spring Data存储库不会加载关系

时间:2015-08-12 22:09:26

标签: java spring jpa caching triggers

当持久化Book对象时,Insert上的触发器会运行以创建事务记录(在单独的表中)。

当我创建Book的实例并保存它时,我希望在transactions()数组中看到此记录,但它一直是空的。

Book book = new Book("Moby Dick", "Melville", "hardcover");
book = bookRepository.saveAndFlush(book);
if( book != null)
    assertTrue("There is no transaction history", book.transactions().size() > 0 );

总是失败。这样做(我试图重新加载数据的旋转):

public int addBook()
{
    int bookID;
    Book book = new Book("Moby Dick", "Melville", "hardcover");
    book = bookRepository.saveAndFlush(book);
    if( book != null)
        bookID = book.getID();
    return bookID;
}

@Test
public void testNewBookTrans()
{
    int aBook = addBook();
    bookRepository.findAll();
    transactionRepository.findAll();
    Book book = bookRepository.findOne(bookID);
    if( book != null )
        assertTrue("Still no transactions", book.getTransactions().size() > 0);
}

然而,如果我让这个测试失败,重启JUnit然后查询同一本书,它就有触发器添加的事务。

因此,必须有一些方法来使db缓存失效或重新加载,但我没有看到它。

1 个答案:

答案 0 :(得分:2)

这是正常行为导致新实体实例被缓存。你必须刷新它。

请参阅this answer

修改 回应你的评论。

关于缓存范围,取决于您在所使用的应用和平台中如何操作它。在公共容器管理事务和持久化上下文案例中," *第1级"缓存范围是持久化上下文,生命周期依赖于底层的tranaction。它在事务范围开始时创建,并在事务范围结束时处理。

我认为上述解决方案对您不可行,因为您不想在您已经找到的每个地方关注引用实例及其集合。 因此,如果提到了持久化上下文的范围,那么在保存它并调用方法flush之后,您可以直接引用该实例。

我的意思是,您可以在保存实例和flush之后编辑代码以引用(您必须刷新到数据库)

Book book = new Book("Moby Dick", "Melville", "hardcover");
book = bookRepository.saveAndFlush(book);
book = bookRepository.refresh(book);
if( book != null)

refresh方法之后(您可能必须implement the custom method),您将拥有该书及其收藏品。

如果要刷新关联的事务处理(它们是实体?),yoo可以将CascadeType.REFRESH添加到Book.transactions集合 太