简体   繁体   English

由于MS SQL中UNIQUE约束的非标准行为,Spring / Hibernate的解决方法

[英]Workaround for Spring/Hibernate due to non-standard behaviour of UNIQUE constraint in MS SQL

There is a UNIQUE database constraint on an index which doesn't allow more than one record having identical columns. 索引上有一个UNIQUE数据库约束,它不允许多个记录具有相同的列。

There is a piece of code, managed by Hibernate (v2.1.8), doing two DAO 有一段代码由Hibernate(v2.1.8)管理,执行两个DAO
getHibernateTemplate().save( theObject )
calls which results two records entered into the table mentioned above. 调用导致两个记录输入上述表格。

If this code is executed without transactions, it results INSERT, UPDATE, then another INSERT and another UPDATE SQL statements and works fine. 如果在没有事务的情况下执行此代码,则会生成INSERT,UPDATE,然后是另一个INSERT和另一个UPDATE SQL语句,并且工作正常。 Apparently, the sequence is to insert the record containing DB NULL first, and then update it with the proper data. 显然,序列是先插入包含DB NULL的记录,然后用适当的数据更新它。

If this code is executed under Spring (v2.0.5) wrapped in a single Spring transaction, it results two INSERTS, followed by immediate exception due to UNIQUE constraint mentioned above. 如果此代码在包含在单个Spring事务中的Spring(v2.0.5)下执行,则会产生两个INSERTS,然后由于上面提到的UNIQUE约束而立即发生异常。

This problem only manifests itself on MS SQL due to its incompatibility with ANSI SQL. 此问题仅在MS SQL上表现出来,因为它与ANSI SQL不兼容。 It works fine on MySQL and Oracle. 它适用于MySQL和Oracle。 Unfortunately, our solution is cross-platform and must support all databases. 不幸的是,我们的解决方案是跨平台的,必须支持所有数据库。

Having this stack of technologies, what would be your preferred workaround for given problem? 拥有这一堆技术,对于给定问题,您最喜欢的解决方法是什么?

You could try flushing the hibernate session in between the two saves. 您可以尝试在两次保存之间刷新休眠会话。 This may force Hibernate to perform the first update before the second insert. 这可能会强制Hibernate在第二次插入之前执行第一次更新。

Also, when you say that hibernate is inserting NULL with the insert, do you mean every column is NULL, or just the ID column? 另外,当你说hibernate用insert插入NULL时,你是说每列都是NULL,还是只是ID列?

I have no experience in Hibernate, so I don't know if you are free to change the DB at your will or if Hibernate requires a specific DB structure you cannot change. 我没有Hibernate的经验,所以我不知道你是否可以随意更改数据库,或者Hibernate是否需要特定的数据库结构,你无法改变。

If you can make changes then you can use this workaround in MSSQL tu emulate the ANSI behaviour : 如果您可以进行更改,那么您可以在MSSQL中使用此变通方法来模拟ANSI行为:

drop the unique index/constraint 删除唯一索引/约束

define a calc field like this: 定义一个这样的calc字段:

alter table MyTable Add MyCalcField as 
case when MyUniqueField is NULL 
      then cast(Myprimarykey as MyUniqueFieldType) 
      else MyUniqueField end

add the unique constraint on this new field you created. 在您创建的新字段上添加唯一约束。

Naturally this applies if MyUniqueField is not the primary key! 当然,如果MyUniqueField不是主键,这也适用! :) :)

You can find more details in this article at databasejournal.com 您可以在databasejournal.com上找到本文的更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 由于 schema.sql 和休眠导致的唯一约束错误 - Unique constraint error due to schema.sql and hibernate 用于非标准JSON的Spring自定义对象映射器 - Spring Custom Object Mapper for non-standard JSON 在 Spring 集成(入站网关)中传递非标准 Header 名称 - Passing non-standard Header names in Spring Integration (inbound gateway) 如何在 Spring 反应的 ServerHttpResponse 中设置非标准的 HttpStatus? - how to set non-standard HttpStatus in Spring reactive's ServerHttpResponse? 在 Spring 中未返回具有非标准 getter 名称的变量 - Variable with non-standard getter name not getting returned in Spring 删除对象时使用Hibernate违反MS-SQL中的UNIQUE KEY约束 - Violation of UNIQUE KEY constraint in MS-SQL using Hibernate when deleting objects MS-SQL快照隔离和休眠行为 - MS-SQL Snapshot Isolation and Hibernate behaviour 解析非标准JSON - Parsing non-standard JSON Spring MVC.java.sql.BatchUpdateException中的休眠错误:违反了唯一约束(OVERFLOW.SYS_C004914) - hibernate error in spring MVC.java.sql.BatchUpdateException: unique constraint (OVERFLOW.SYS_C004914) violated 在Spring Batch 3.0.x中-如何为非标准数据库设置数据库类型? - In Spring Batch 3.0.x - How to set database type for Non-standard Database?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM