Spring Boot 中如何处理异常“错误:重复的键值违反唯一约束”

问题描述 投票:0回答:1

我在 PostgreSQL 中有一个表 user_asset,其中包含列 id、user_id、code(类型 - 整数、约束 - user_asset_code_unique)。

user_asset

id  user_id  code
1     97     7752
2     98     7753 
3     99     7754

@Repository
public interface AssetRepository extends JpaRepository<UserAsset, Integer> {}

@Entity
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user_asset", schema = "public")
public class UserAsset {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;


    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "code")
    private MPID mpid;
}

private final AssetRepository assetRepository;

@Transactional
public UserAssetResponse update(UserAssetRequest dto){
    //some code here

    User user = userRepository.findById(dto.getID());

    addAssets(user, dto.getAssets());
} 

private void addAssets(User user, List<Long> assets){

    List<UserAsset> newAssets = mpidRepository.findAllById(assets).stream()
            .map(item -> UserAsset.builder().user(user).mpid(item).build())
            .collect(Collectors.toList());
    
    assetRepository.saveAll(newAssets);
}

我从邮递员那里发送:

{
    "id": 97,
    "assets": [7753,7754]
}

正如您从上面的数据库示例中看到的:

id  user_id  code
1     97     7752

我尝试更新[7753,7754]代码

当我尝试更新 UserAssetResponse 并设置现有代码 column 时,我遇到了异常。 在邮递员上我看到:

500 Internal server error
{
    "message": "could not execute statement; SQL [n/a]; constraint [user_asset_code_unique]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
}

在IDEA上错误是:

o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: duplicate key value violates unique constraint "user_asset_code_unique"
  Detail: Key (mpid_id)=(7753) already exists.

我知道这是因为列code约束[user_asset_code_unique]而发生的。 问题是我不知道这个异常发生在哪里以及如何处理这个异常。 我尝试这个解决方案,我知道捕获异常是错误的,但它没有帮助。

try{
  assetRepository.saveAll(newAssets);          
}catch (Exception e){
  e.printStackTrace();
}
java spring spring-boot hibernate spring-mvc
1个回答
0
投票

如果您查看异常打印出来的堆栈跟踪,就会告诉您异常的来源。另外,除非抛出的异常是 RuntimeException 或 Exception 之外的其他类型的 Thorowable,否则您的 try-catch 块应该捕获它。您是否在调试模式下运行它并在 catch 块中设置断点?

© www.soinside.com 2019 - 2024. All rights reserved.