当持久化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缓存失效或重新加载,但我没有看到它。
答案 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
集合
太