由于MS SQL中UNIQUE约束的非标准行为,导致Spring / Hibernate的变通办法
时间:2020-03-06 14:42:47 来源:igfitidea点击:
索引上有一个UNIQUE数据库约束,该约束不允许多个记录具有相同的列。
有一段代码由Hibernate(v2.1.8)管理,执行两个DAOgetHibernateTemplate()。save(theObject)
调用会导致将两个记录输入到上述表中。
如果执行此代码时没有事务,则结果为INSERT,UPDATE,然后生成另一个INSERT和另一个UPDATE SQL语句,并且工作正常。显然,顺序是先插入包含DB NULL的记录,然后使用适当的数据对其进行更新。
如果此代码在包装在单个Spring事务中的Spring(v2.0.5)下执行,则将导致两个INSERTS,然后由于上述UNIQUE约束而导致立即异常。
由于与ANSI SQL不兼容,此问题仅在MS SQL上体现出来。它可以在MySQL和Oracle上正常工作。不幸的是,我们的解决方案是跨平台的,必须支持所有数据库。
拥有这种技术堆栈,对于给定的问题,我们首选的解决方法是什么?
解决方案
我没有Hibernate的经验,所以我不知道我们是否可以随意更改数据库,或者Hibernate是否需要我们无法更改的特定数据库结构。
如果可以进行更改,则可以在MSSQL tu中使用此替代方法来模拟ANSI行为:
删除唯一索引/约束
定义一个calc字段,像这样:
alter table MyTable Add MyCalcField as case when MyUniqueField is NULL then cast(Myprimarykey as MyUniqueFieldType) else MyUniqueField end
在我们创建的这个新字段上添加唯一约束。
如果MyUniqueField不是主键,这自然适用! :)
我们可以在databasejournal.com上的本文中找到更多详细信息。
我们可以尝试在两次保存之间刷新休眠会话。这可能会迫使Hibernate在第二次插入之前执行第一次更新。
另外,当我们说休眠在插入时插入NULL时,我们是说每个列都是NULL,还是ID列?