为了账号安全,请及时绑定邮箱和手机立即绑定

JPA 保存多个实体,在 Spring @Transactional 内部并启用

JPA 保存多个实体,在 Spring @Transactional 内部并启用

慕森王 2023-07-28 10:42:47
我已经研究了好几个小时了,但当我将实体保存在封装事务中时,我找不到一种方法来绕过 JPARepository 自动启动/提交事务的问题。我总共创建了 3 个实体。前 2 个实体将被创建,以便在创建第三个实体时ClientAdmin,实体可以在持久化之前形成关系。CreditPotInstitution当抛出异常时,我希望它能够使创建的实体不被提交(即整个过程回滚)。目前,我可以在日志中看到 JPA Save 方法可能会启动自己的事务(我不完全理解日志),这会导致已调用的实体repo.save(entity)在自己的事务中提交?任何帮助将不胜感激。    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)public void createInstitution(InstitutionSignUpForm form) throws Exception {    //Create Admin account.    ClientAdmin clientAdmin = new ClientAdmin();    clientAdmin.setRole(roleRepo.findOneByRole("SUPER_ADMIN").orElseThrow(() -> new Exception("Can not resolve role SUPER_ADMIN")));    clientAdmin.setPassword(passwordEncoder.encode(form.getPassword()));    clientAdmin.setUsername(form.getUsername());    clientAdmin = clientAdminRepo.save(clientAdmin);    //Create Credit Pot for institution.    CreditPot creditPot = new CreditPot();    creditPot.setIsPrimaryPot(true);    creditPot.setName("Primary Credit Pot");    creditPot.setCredits(300L);    creditPot = creditPotRepo.save(creditPot);    System.out.println("Throwing Exception.");    if(1==1) throw new Exception("!!!", new Throwable("!!!"));    //Create institution and assign relationships.    Institution institution = new Institution();    institution.setDiceCode(dicewareGenerator.generateRandomPassword(6));    institution.setName(form.getInstitutionName());    institution.setPrimaryCreditPot(creditPot);    clientAdmin.setInstitution(institution);    institutionRepo.saveAndFlush(institution);}
查看完整描述

1 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

MySQL 历史上默认使用 MyISAM 引擎创建表,该引擎不支持事务。后来添加了 InnoDB,它确实支持事务,但是 MyISAM 在相当长的一段时间内仍然是默认值。

Hibernate 及其方言遵循相同的默认值,因此 MySQL 方言的默认值是 MyISAM(为了向后兼容)。

有两种方法可以解决此问题:选择特定方言或使用特定属性从 MyISAM 切换到 InnoDB。

要选择方言,请使用spring.jpa.database-platform来指定所需的依赖项。

spring.jpa.database-platform=org.hibernate.dialect.MySQL57InnoDBDialect`

或设置属性使用

spring.jpa.properties.hibernate.dialect.storage_engine=innodb

或两者的组合(因为MySQL57InnoDBDialect现在已弃用该hibernate.dialect.storage_engine属性)。

spring.jpa.database-platform=org.hibernate.dialect.MySQL57Dialect
spring.jpa.properties.hibernate.dialect.storage_engine=innodb
查看完整回答
反对 回复 2023-07-28
  • 1 回答
  • 0 关注
  • 66 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信