2012-04-01 25 views
0

如果我有一个标记为@Transactional的测试方法,并且我在任何时间点将实体保存到数据库,我应该能够获取新的东西(包含更改)在下一行代码中,即使事务将被回滚(事务性单元测试的默认行为),对吧?确保Hibernate持久性在junit测试中工作

换句话说,如果我有以下几点:

thisPhoto.likes.add(thisUser); 
thisPhoto.save(); //the hibernate session will save this instance 
... 
thisUser = User.get(thisUser.id) // I even take the user instance again 
newPhoto = thisUser.likedPhotos.get(0); //this should already contain the new photo, right? 
assertEqual(newPhoto, thisPhoto); 

想象一下,照片和用户都是基于Hibernate的实体,所有的关系都正确设置和一切。

然而,当我到达的最后一行代码中,我得到一个例外,那likedPhotos收集具有0大小,并没有元素的索引0

为什么?我还应该如何测试该实体是否被正确保存?

回答

0

save不立即保存。您必须登录flush会话,以确保所做的更改实际持久保存到数据库。

+0

实际上,我甚至不希望它达到数据库。我相信Hibernate。我实际上期望的是,当探测已经更新的实体时,即使尚未将更改保存到数据库中,当前会话也会给我一个更新的实体。我想我有点不对,对吧? – preslavrachev 2012-04-01 17:57:48

+0

实际上,即使手动刷新会话,然后重新计算对象不会返回一个更新的:( – preslavrachev 2012-04-01 18:48:07

+0

你使用的是mysql吗?你有自动提交吗? – hvgotcodes 2012-04-01 23:37:17

0

首先,您不应该直接处理属于Photo的列表,而不需要致电Photo.getLikes()。在大多数情况下,这被认为是不好的面向对象的风格。其次,对于大多数域对象,完全不允许编辑其集合是非常正常的。你应该问Photo更新它的列表如下:Photo.addLikedUser(User)。然后,您可以通过在Photo.getLikes()方法中返回Collections.unmodifiableSet(this.likes)来锁定列表进行编辑。

最后,为了解决您的问题,您可能需要在Photo.addLikedUser(User)方法中调用User.addLikedPhoto(Photo)。我不确定Hibernate会为你做这些事情,特别是在调用flush之前。