所以我正在使用Grails。我的应用程序涉及一个对象进入,并在数据库中更新并返回。这是我试图在Spock IntegrationSpec中测试的这种行为。
基本上,我的测试看起来像这样(伪代码)
setUp
{
Session sess = sessionFactory.openSession();
Transaction tx = null;
try{
...
//These loaded fixtures include the shop
//that I want to update
fixtures = fixtureLoader.load(fixtureLocationsArray)
...
tx.commit()
...
sessionFactory.currentSession.flush()
sessionFactory.currentSession.clear()
}
void testUpdate()
{
Shop shop = fixtures.shop
shop.discard()
//Pure, unadulterated desperation below
sessionFactory.currentSession.flush()
sessionFactory.currentSession.clear()
sessionFactory.getCache().evictEntityRegion(Shop)
ShopDTO shopDto = convertToDTO(shop)
shopDto.name = "Updated Shop"
//Chokes while in the controller
returnedShopDTO = dtoController.update(shopDto)
}
我已经尝试了一切,包括将我的夹具创建包装在一个事务中,驱逐,丢弃并尽我所能使会话“忘记”对象。无论我做什么,我总会得到像
这样的错误org.hibernate.StaleObjectStateException:
Row was updated or deleted by another transaction
(or unsaved-value mapping was incorrect)
或者会抱怨会话中已存在具有该ID的内容。据我所知,整个测试发生在一个胖子会议中。因此,当我进入“更新”时,它会插入夹具,然后调用“select last_row_id”或其他东西。然后它将下一个ID分配给我更新的商店。所以最后,如果它没有崩溃,我得到两个插入,第一个来自fixture,第二个来自我的保存/合并调用。
非常感谢任何关于创建灯具的帮助,然后让它们从会话/事务/ doo-hickey中消失。
答案 0 :(得分:0)
原来我必须在我的项目上禁用版本控制。我通过将以下代码添加到我的域类中来完成此操作。我不确定这是否是正确的解决方案,但它会使各种错误消失。
static mapping = {
...
version false
...
}