除了捕获异常并重试之外,还有一种更好的方法来更新版本化的实体吗?下面是代码
@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);
}
}
}
}
}
}
输出如下所示休眠:将值(?,?,?,?,?)插入到员工(佣金,姓名,版本,employee_id,input_date)中休眠:将值(?,?,?,?,?)插入到员工(佣金,姓名,版本,employee_id,input_date)中休眠:将值(?,?,?,?,?)插入到员工(佣金,姓名,版本,employee_id,input_date)中休眠:将值(?,?,?,?,?)插入到员工(佣金,姓名,版本,employee_id,input_date)中2019-10-15 16:43:10.372 WARN 17216 --- [main] o.h.engine.jdbc.spi.SqlExceptionHelper:SQL错误:1,SQLState:230002019-10-15 16:43:10.372错误17216 --- [main] o.h.engine.jdbc.spi.SqlExceptionHelper:ORA-00001:违反了唯一约束(I706446.SYS_C008493)
休眠:选择employee0_.employee_id作为employee_id1_0_,employee0_.input_date作为input_date2_0_,employee0_.commission作为提要3_0_,employee0_.name作为name4_0_,employee0_.version作为version5_0_,来自employee employee0_,其中employee0_.employee_id =?和employee0_.input_date =?休眠:从员工employee0_中选择employee0_.employee_id作为employee_id1_0_,employee0_.input_date作为input_date2_0_,employee0_.commission作为提要3_0_,employee0_.name作为name4_0_,employee0_.version作为version5_0_,其中employee0_.employee_id =?和employee0_.input_date =?休眠:从员工employee0_中选择employee0_.employee_id作为employee_id1_0_0 __,employee0_.input_date作为input_date2_0_0_,employee0_.commission作为提要3_0_0_,employee0_.name作为名称4_0_0_,employee0_.version作为version5_0_0_,其中employee0_.employee_id =?和employee0_.input_date =?休眠:更新员工设置的佣金= ?,名称= ?,版本=?其中employee_id =?和input_date =?和版本=?
我希望休眠状态发布“版本”列的更新递增
您的期望不正确。您使用的版本不是预期的版本。版本控制的目的是提供乐观锁定,而不仅仅是指出实体已更改了多少次。预期的使用场景如下:之前更新实体,您应该从数据库中读取它,然后进行修改,然后保存。 Hibernate会检查您要保存的版本是否与数据库中的版本相同。
A)如果相同,它将自动增加版本并保存您的实体,即它将更新数据库中的现有记录。
B)如果您要保存的实体中的版本小于数据库中的版本,则表示您正在尝试保存过时的版本。这意味着您不知道在此期间所做的更改。在这种情况下,Hibernate将引发异常。