微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JPA CrudRepository 关于删除 DataIntegrityViolationException 错误消息

如何解决JPA CrudRepository 关于删除 DataIntegrityViolationException 错误消息

我有一个 Spring Boot 应用程序,它在 h2 数据库中有 2 个表:计算机一个 处理器

计算机和处理器之间存在单向、多对一关系,因此许多计算机可以有一个处理器。在架构中,关系上存在外键约束,因此您不能删除某些计算机正在使用的处理器。

我希望能够向用户显示有用的错误消息,例如:“无法删除处理器‘M1’,因为它被计算机‘MacBook、MacBook Pro’使用。 ” 我能够成功捕获 DataIntegrityViolationException 但是这个错误没有包含足够的信息让我生成所需的错误消息。它只提到存在违反foreignKeyConstraint 定义。

因此,作为一种解决方法,当抛出 DataIntegrityViolationException 时,我会捕获它并查询特定实例的数据库,为什么无法删除处理器并以这种方式生成错误消息。我可以很容易地不在架构中添加 FK 约束,只需检查服务中的数据库以确保要删除的处理器未在数据库中的任何计算机中使用,并生成适当的错误。然而,以编程方式检查 FK 约束感觉就像代码味道一样。

有没有办法在数据库级别使用 FK 约束并使用 DataIntegrityViolationException 生成有用的错误消息?

// ENTITIES
@Entity
@Table(name = "Computer",schema = "CS")
public class Computer extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "computer_id")
    @Getter
    @Setter
    private long id;
    ...
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "processor_id")
    @OnDelete(action= OnDeleteAction.NO_ACTION)
    @Getter
    @Setter
    private Processor processor;
    ...
}

@Entity
@Table(name = "Processor",schema = "CS")
public class Processor extends BaseEntity {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Column(name = "processor_id")
     @Getter@Setter
     private long id;
    ...
}

 // PROCESSOR_CONTROLLER
 public ResponseEntity<Void> deleteByName(@PathVariable("name")) String name) {
   try {
        processorService.deleteByName(name);
   } catch (DataIntegrityViolationException e) {
       List<String> computerList = new ArrayList<>();
       computerService.findAllByHoldName(name).forEach(computer -> computerList.add(computer.getProcessor()));
       String computeRSString = computersList.stream().reduce("",(res,next) -> res += next + ",");
       throw new DataIntegrityViolationException (String.format("Processor '%s' is used by Computer(s) '%s'. It cannot be deleted.",name,computeRSString));
   }
   return ResponseEntity.noContent().build();
}

// PROCESSOR_SERVICE
@Transactional
public void deleteByName(String name) {
    Processor existingProcessor = processorRepository.findByName(name);
    processorRepository.delete(existingProcessor);
}

预先感谢您的帮助!!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。