Spring CrudRepository 可能抛出哪些 RuntimeException?

74

我有这个 Spring Data CrudRepository,用于处理数据库上的CRUD操作。

@Repository
public interface IUserRepository extends CrudRepository<User, String> {

}

User是我的数据库中用户表的实体。 CrudRepository向存储库添加以下操作:

  • delete(String ID)
  • findOne(String ID)
  • save(User user)

根据文档,删除和查找操作在给定的ID为空时会抛出IllegalArgumentException异常,而保存操作不会抛出任何异常。

问题在于CrudRepository的javadoc没有提到这些操作抛出的其他异常。例如,它没有说明delete(String ID)操作在所提供的ID不存在于DB中时会抛出EmptyResultDataAccessException异常。

save(User user)操作的javadoc中,不清楚在插入违反一些数据完整性约束的新用户时抛出哪些异常(如唯一字段和外键)。此外,它也没有警告你是否正在写入新用户或现有用户:它只是创建一个新用户或者覆盖现有用户(因此它是插入加更新操作)。

在企业应用程序中,我应该能够捕获每个操作可能引发的可抛出异常,并且我应该在操作的javadoc中了解到这一点。

您知道有关CrudRepository异常的任何清晰文档吗?

2个回答

113

Spring具有内置的异常转换机制,以便所有JPA持久性提供程序抛出的异常都被转换为Spring的DataAccessException - 针对所有使用@Repository注释(或已配置的)的bean。

这里有四个主要的组别:

  • NonTransientDataAccessException - 这些是在未纠正异常原因的情况下重试相同操作将失败的异常。例如,如果您传递不存在的id,则会失败,除非该id存在于数据库中。

  • RecoverableDataAccessException - 这些是前者的“相反” - 可以通过某些恢复步骤进行恢复的异常。API文档中有更多详细信息。

  • ScriptException - 与SQL相关的异常,例如尝试处理不良形式的脚本时。

  • TransientDataAccessException - 这些是可以在没有任何显式步骤的情况下进行恢复的异常,例如,当数据库超时时,您可以在几秒钟后重试。

也就是说,查找有关所有异常的理想位置-在API本身中-只需通过DataAccessException的层次结构浏览即可。


2
感谢您提供所有异常链接并详细解释它们的含义。 - Ian Newland
14
@vtor你所说的“内置异常翻译机制”是什么意思?我很好奇为什么Spring文档没有明确说明一些方法会抛出DataAccessException异常,比如CrudRepository类的save方法。 - fsimon
1
出于好奇,你是怎么学会这个的?我在哪里可以学到这个,而不必求助于 Stack Overflow? - VGR
关于异常和事务注释的一个问题,如果我捕获了任何一个异常,回滚仍然会发生吗?因为也许我需要做一些像通知服务这个失败的事情,但我仍然希望由Transactional注释触发回滚(如果发生任何此类异常,但最终我认为是DataAccessException)。 - BugsOverflow

1

我捕获了父异常DataAccessException。

import org.springframework.dao.DataAccessException;

enter image description here


我遇到了巨大的问题。一整天都在尝试解决这个问题。当发生这种情况时,我想抛出Http状态异常。 - user16422658
我在catch块中使用了Exception类型,但仍然出现了不触发catch块的唯一约束错误。这是什么原因? - Veswanth
@Veswanth,你有没有抓到它? - BugsOverflow
如果你这样做(捕获DataAccessException),回滚是否仍会被触发?例如,这些Jpa方法都有Transactional注释,它确保如果出现任何问题,它将回滚事务,如果你捕获了这个异常,它仍然会发生吗? - BugsOverflow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接