当前位置: 首页 > 知识库问答 >
问题:

Spring JPA版本化实体Hibernate错误

龙玺
2023-03-14

除了捕获异常和重试之外,还有更好的方法来更新版本化实体吗?下面是代码

@Entity
@AllArgsConstructor
@Builder
@NoArgsConstructor
@Data
@IdClass(com.test.domain.EmployeeKey.class)
public class Employee {
    @Id
    private Integer employeeId;
    private String name;
    private Double commission;
    @Id
    private LocalDate inputDate;
    @Version
    private Integer version;
}

public class EmployeeKey  implements Serializable {
    private Integer employeeId;
    private java.time.LocalDate inputDate;
}

@SpringBootApplication
@Slf4j
public class SampleApplication {

    public static void main(final String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }

    @Component
    public class AppStartupRunner implements ApplicationRunner {
        @Autowired
        EmployeeRepo employeeRepo;
        @Override
        public void run(ApplicationArguments args) throws Exception {
            log.info("Your application started with option names : {}", args.getOptionNames());
            List<Employee> empList = new ArrayList();
            Employee employeeComm1 = Employee.builder().employeeId(1).name("Sam").commission(100.45).inputDate(LocalDate.of(2019,10,01)).build();
            Employee employeeComm2 = Employee.builder().employeeId(1).name("Sam").commission(87.54).inputDate(LocalDate.of(2019,10,01)).build();
            Employee employeeComm3 = Employee.builder().employeeId(2).name("John").commission(56.78).inputDate(LocalDate.of(2019,10,01)).build();
            Employee employeeComm4 = Employee.builder().employeeId(3).name("Katie").commission(65.23).inputDate(LocalDate.of(2019,10,01)).build();

            empList.add(employeeComm1);
            empList.add(employeeComm3);
            empList.add(employeeComm4);
            empList.add(employeeComm2);
//            employeeRepo.saveAll(empList);
            for (Employee emp: empList) {
                try {
                        employeeRepo.save(emp);
                    }
                 catch(Exception e) {
                     if (employeeRepo.findByEmployeeIdAndInputDate(emp.getEmployeeId(), emp.getInputDate()).isPresent()) {
                         Employee empFromDb = employeeRepo.findByEmployeeIdAndInputDate(emp.getEmployeeId(), emp.getInputDate()).get();
                         empFromDb.setCommission(emp.getCommission());
                         empFromDb.setName(emp.getName());
                         employeeRepo.save(empFromDb);
                     }

                }
            }

        }
    }
}

输出如下:Hibernate:插入员工(佣金、姓名、版本、员工id、输入日期)值(?、?、?、?、?)Hibernate:在员工(佣金、姓名、版本、员工id、输入日期)中插入值(?、?、?、?、?)Hibernate:在员工(佣金、姓名、版本、员工id、输入日期)中插入值(?、?、?、?、?)Hibernate:在员工(佣金、姓名、版本、员工id、输入日期)中插入值(?、?、?、?、?)2019-10-15 16:43:10.372警告17216-[主]o.h.发动机。jdbc。spi。SqlExceptionHelper:SQL错误:1,SQLState:23000 2019-10-15 16:43:10.372错误17216-[主]o.h.engine。jdbc。spi。SqlExceptionHelper:ORA-00001:违反了唯一约束(I706446.SYS\u C008493)

Hibernate:选择employee0_employee_id为employee_id1_0_,employee0_input_dateinput_date2_0_,employee0_.佣金为commission3_0_,employee0_. name为name4_0_,employee0_. version为version5_0_从员工employee0_employee0_employee_id=?和employee0_。input_date=?Hibernate:选择employee0_employee_id为employee_id1_0_,employee0_input_date为input_date2_0_,employee0_.佣金为commission3_0_,employee0_. name为name4_0_,employee0_. version为version5_0_从员工employee0_employee0_.employee_id=?和employee0_。input_date=?Hibernate:选择employee0_.employee_id为employee_id1_0_0_,employee0_<--plhd--17/>。input_date为input_date2_0_0_,employee0_.佣金为commission3_0_0_,employee0_. name为name4_0_0_,employee0_. version为version5_0_0_从员工employee0_employee0_。employee_id=?和employee0_。=input_date?Hibernate:更新员工设置佣金=?,名称=?,版本=?employee_id=?和input_date=?和版本=?

共有1个答案

颜奇希
2023-03-14

我希望hibernate发布版本列递增的更新

您的期望是不正确的。您使用的版本不是预期使用的版本。版本控制的目的是提供乐观锁定,而不是简单地指示实体更改了多少次。预期的使用场景如下:在更新实体之前,您应该从数据库中读取它,然后修改,然后保存。Hibernate检查您尝试保存的版本是否与数据库中的版本相同。

A)如果相同,它会自动增加版本并保存您的实体,即更新数据库中的现有记录。

B) 如果您试图保存的实体中的版本低于数据库中的版本,则表示您试图保存的是过时的版本。这意味着您不知道在此期间所做的更改。在这种情况下,Hibernate将引发异常。

 类似资料:
  • 我读过一些关于hibernate的话题 “如果实体实例作为分离对象通过值传递,例如通过会话bean的远程业务接口,则类必须实现可序列化接口。”(c) 我有:使用Hibernate的简单Spring MVC项目。我有MyEntityDataTable,并且可以通过应用程序中的用户编辑它。 > 用户向getMyEntity()发出请求,并获取空的MyEntity对象 然后在表单中他设置了所有需要的参数

  • 问题内容: 我有一个由Hibernate加载的实体(通过): 此类由Hibernate Envers审核。如何加载用户实体的先前版本? 问题答案: 也许然后(来自AuditReader文档) (我对此很陌生,不确定我是否所有语法都正确,也许size()-1应该是size()-2吗?)

  • 问题内容: 有谁知道那里是否有一个能够从实体类中剥离Hibernate集合以使其可序列化的框架?我看了一下BeanLib,但它似乎只做实体的深层副本,而不允许我为实体类中的集合类型指定实现映射。BeanLib当前不适用于Hibernate 3.5和Spring 3(我确实修改了源代码并能够使其正常工作,但我不想这样做)。吉利德(Gilead)似乎是一个选择,但似乎颇具侵略性。我宁愿使用简单的深度复

  • 我知道关于这个问题已经有一些问题,但我认为这个问题是不同的。 稍后,我使用JPA all()从存储库中获取all;我从列表中选择一个对象并更改描述。 然后我想使用JPA merge()更新存储库中的对象(参见代码)。 这里的问题是,它在我第一次尝试更改描述时起作用(版本值现在是2)。第二次,将引发一个OptimisticLockException表示该对象同时被更改。 B.ChangeDescri

  • 尝试获取父实体(Msg)的实体,其中父PK (msg_id)是子实体中的FK时,尝试保持子实体(MsgRetry)时出错。 错误,如:org.hibernate.id.IdentifierGenerationException:试图从null一对一属性分配id 父实体,不需要知道子实体(至少我认为它不需要知道)。一旦子实体被持久化,我就会尝试也持久化父实体。我可以通过在子实体中没有父实体并调用关联

  • 问题内容: 我已经为此厌倦了很长时间。我不知道是什么原因导致此错误。这是我的文件: Uzytkownik.hbm.xml hibernate.cfg.xml: 我使用的是MySQL 5.5。 我收到以下错误: 这是我的课程:main.java Uzytkownik.java: HibernateUtil.java: 问题答案: 也许您的映射文件不完整,但其他方面应该是: =>需要设置完全合格的类名