假设我将表定义为:
CREATE TABLE ITEMS(
ID BIGINT PRIMARY KEY,
NAME VARCHAR2,
CONSTRAINT NAME_IS_UNIQUE UNIQUE (NAME)
);重要的部分是NAME_IS_UNIQUE约束。
对应的POJO项为:
class Item{
private Long id;
private String name;
/** getters and setters */
}以及SQL对象接口,其方法定义如下:
@SqlUpdate("insert into items(id, name) values(:id, :name)")
int insert(@BindBean Item itemToInsert);如果我将尝试插入到已有名称的项中,那么我将获得关于constraint NAME_IS_UNIQUE违规的DB供应商特定的SQLException。
有没有一种方法可以在SQLException和特定于应用程序的异常(例如ItemNameUniqueConstraintException)之间提供映射,以便insert方法基本上将其签名更改为类似下面的签名?
@SqlUpdate("insert into items(id, name) values(:id, :name)")
int insert(@BindBean Item itemToInsert) throws ItemNameUniqueConstraintException;问题不是关于特定的唯一约束,而是更多地关于一般情况,其中SQLException可以涉及任何事情:例如违反引用完整性或检查约束违反等。
发布于 2021-01-28 16:50:54
目前还没有支持的方法来处理SQLException -> ApplicationException映射,您可以在issue中阅读讨论和推理。
但您可以使用default方法的变通方法并手动处理异常,例如:
class ItemNameUniqueConstraintException extends Exception {
public ItemNameUniqueConstraintException(String message, Throwable cause) {
super(message, cause);
}
}
interface Repository {
default void insert(String name) throws ItemNameUniqueConstraintException {
try {
_insert(name);
} catch (JdbiException e) {
if (e.getCause() instanceof SQLException) {
var cause = (SQLException) e.getCause();
if (cause.getSQLState().equals("11111")) {
throw new ItemNameUniqueConstraintException("Name not unique.", cause);
}
}
// ...
}
}
@SqlUpdate("INSERT INTO test (name) VALUES (:name)")
void _insert(@Bind("name") String name);
}它不是很漂亮,但可以通过为存储库和JDBI实现的契约单独使用接口来改进,这样就可以不向调用者公开_insert和类似的方法。
https://stackoverflow.com/questions/65653092
复制相似问题