【问题标题】:Spring Data JPA + Oracle Trigger increments the ID twiceSpring Data JPA + Oracle Trigger 将 ID 增加两次
【发布时间】:2019-05-14 20:56:27
【问题描述】:

我使用以下技术栈:

  • spring-boot-starter-data-jpa
  • 用于连接池的 HikariCP
  • Oracle 数据库

我的实际代码与此类似。

   /// My trigger looks like this
   CREATE OR REPLACE TRIGGER FILE_BRI
     BEFORE INSERT
     ON FILE
     FOR EACH ROW
     BEGIN
       SELECT FILE_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
     END;
   ///

   public class FILE implements Serializable {
          @Id
        @SequenceGenerator(
                name = "FILE_SEQ",
                sequenceName = "FILE_SEQ",
                allocationSize = 1)
        @GeneratedValue(
                strategy = GenerationType.SEQUENCE,
                generator = "FILE_SEQ"
        )
        private long id;
    }

    public class ServiceA () {

        @Transactional(propagation = REQUIRES_NEW, isolation = READ_COMMITTED) 
        public File insertFile() {
         // Below line returns the inserted File object with ID as '58496'
           return fileRepository.save(file)
        }

        @Transactional(propagation = REQUIRES_NEW, isolation = READ_COMMITTED) 
        public AccessControl insertAccessControl() {
        // Below line results in 'SQLIntegrityConstraintViolationException' (full error at the bottom of this post)
            return accessControlRepository.save(accessControlFile)
         }
     }

     Public class FileProcessor() {
       ServiceA serviceA;
       public void someMethod() {
         // insert the file and get the inserted record
           File insertedFile = serviceA.insertFile(file);

         // get the ID from the inserted file and make another insert into another table
           serviceA.insertAccessControl(insertedFile.getId()); // inserted file ID is '58496'
        }
     }

这是我的调查:

当我验证表“FILE”中插入记录的 ID 是“58497”时,repository.save() 返回了不同的值。 当我在表“ACCESS_CONTROL_FILE”上进行第二次插入时,FILE_ID 为 '58496' 会导致以下错误,因为 ID 为 '58496' 的文件不存在。

原因:java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("DB_OWNER"."ACCESS_CONTROL_FILE"."FILE_ID")

我很困惑为什么repository.save() 返回的 ID(即 ID=58496)与数据库中实际插入的 ID(ID=58497)不同!

我调查了互联网上所有与“传播和隔离”相关的选项。

【问题讨论】:

  • 看起来序列在数据库级别又增加了一次。您是否在 db 检查过是否有触发器或序列正在执行此操作?
  • @jusermar10,好一个,我没想到。我正在将那个特定的触发器添加到我的帖子中。看起来触发器试图为每一行创建一个唯一的主键。你能确认它是真是假吗?
  • 是的,它导致了这个问题。如果您希望 jpa 负责序列生成,请禁用触发器
  • 出于某种其他原因,我不想完全禁用/删除触发器,我在这里找到了一个替代解决方案stackoverflow.com/a/8003294/4262073,它根据尚未创建 ID 的条件抑制触发器。不过,感谢@jusermar10 的指点。

标签: oracle hibernate jpa spring-data-jpa database-trigger


【解决方案1】:

如 cmets 中所述,看起来是数据库触发器导致了该问题。禁用触发器以让 JPA 管理 ID 生成。

【讨论】:

    猜你喜欢
    • 2017-09-23
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 2018-02-02
    • 2018-11-24
    • 2017-06-07
    相关资源
    最近更新 更多