保存新实体时{HibernateOptimisticLockingFailureException

时间:2018-03-08 10:00:01

标签: java mysql spring hibernate

我想保存的实体是父母和孩子。当我保存实体(即同时保存的父节点和子节点)时,无论正常执行(每次调试模式),我都会在会话刷新期间抛出HibernateOptimisticLockingFailureException。测试是在我的本地机器上,单线程,没有人正在更改实体,因为我也在保存它。

我们正在使用以下内容:

  1. MySQL v5.5.x
  2. Hibernate 4.3.11
  3. Java 8
  4. Spring 4.1.0
  5. 关键点:

    1. 父母和孩子之间的关系是双向的一对多。
    2. 我们使用乐观锁定,版本列是MySQL在插入期间或更新期间创建的时间戳。在版本字段中,我们指定 @Generated(GenerationTime.ALWAYS)以确保自动从数据库获取版本详细信息(避免Java和MySQL之间的时间精度问题)
    3. 在保存新实体(id = 0)期间,我可以看到实体插入数据库的日志,我还可以看到插入数据库的子实体(通过Hibernate日志)。在此过程中,我还可以看到已完成选择以从数据库中获取版本详细信息。
    4. 在插入实体并刷新会话后不久,对集合进行了脏检查,并在日志中看到该消息未引用的消息。在此之后,我看到父实体表上的更新语句,这是问题发生的地方,因为update语句中使用的版本值与数据库中的版本值不同, HibernateOptimisticLockingFailureException 异常是抛出。
    5. Hibernate代码

      getHibernateTemplate().saveOrUpdate(parentEntity);
      
      // a break point here and wait for 1 sec before executing
      // always get the HibernateOptimisticLockingFailureException
      getHibernateTemplate().flush();
      

      父映射

      @Access(AccessType.FIELD)
      @OneToMany(mappedBy="servicePoint", fetch=FetchType.EAGER, cascade={CascadeType.ALL}, orphanRemoval=true, targetEntity=ServicingMeter.class)
      private List<ServicingMeter> meters = new ArrayList<ServicingMeter>();
      

      儿童制图

      @Access(AccessType.FIELD)
      @ManyToOne(fetch=FetchType.EAGER, targetEntity=ServicePoint.class)
      @JoinColumn(name="service_point_id", nullable=false)
      private ServicePoint servicePoint;
      

      问题
      1.为什么父表上有更新日期?
      2.如何避免此更新发生? 3.我的一对多映射的设置方式有问题吗?

      带注释的日志文件可以是found here

0 个答案:

没有答案