在违反约束时默默地失败

时间:2012-10-09 12:54:28

标签: java sql spring hibernate

我有实体Foo,它使用一些独特的约束映射到sql表。因此保存Foo可能会失败。我使用FooDao保存Foo

@Repository
public class FooDao
{
  @Autowired
  private SessionFactory sessionFactory;

  @Transactional
  @Override
   public void add(Foo item) {
    sessionFactory.save(item);
   }
}

当我调用方法FooDao#add(Foo)时,它可能会失败有两个原因:要么因为唯一约束违规(在这种情况下,我知道如何处理问题),要么是因为其他一些问题(在此我可能应该传播例外)。我如何区分这两种情况?

我可以将方法find(Foo item)添加到FooDao,然后检查我尝试添加的项目是否为数据库。但这需要从数据库中进行额外的选择,我对此有点担心。

4 个答案:

答案 0 :(得分:1)

实际上是SQLState。

做这样的事情

Catch(HibernateException he){
   SQLException sqe = he.getSQLEception();
   String sqlState = sqe.getSQLState();
   if(sqlState.equals("23000"){
       // Handle your exception
   } 
}

Java doc: SQLState - 标识异常的XOPEN或SQL:2003代码

我找到了ISO sqlStates的一个链接,

link to reference

但寻找确切的参考和价值..

答案 1 :(得分:0)

一个明显的(但可能是讨厌的)解决方案是捕获javax.persistence.PersistenceException并解析错误消息“violant”或“constraint”。

从我的角度来看,你应该先选择/找到。请记住,您正在使用ORM! Hibernate有缓存,所以select / find和key contraint错误都不是实际db查询的结果,而是基于你已经在缓存加载数据中计算Hibernate的结果。

塞巴斯蒂安

答案 2 :(得分:0)

Catch org.hibernate.JDBCException。这有getErrorCode()。对于独特的约束声音,其ORA-00001。

-Maddy

答案 3 :(得分:0)

如果存在数据库异常,则会在HibernateException中捕获,这是一个已检查的异常。 SpringController包裹在DataAccessException中,但未经检查。此异常将运行到Servlet并运行到{{1}},并最终进入浏览器和日志文件中的堆栈跟踪。您可以捕获此异常并将其打印出来,以便您可以看到正在发生的事情。这至少可以让你知道究竟是什么在破坏。

坏键可能是一个问题。但糟糕的价值可能是另一个。一些非空字段为空,或者某些东西不够长/短等。修复此问题可能涉及验证。您可以使用Hibernate Validator。你给你的字段添加了一些漂亮的注释,然后在你进入数据库之前在java中得到验证错误 - 错误发生得更快。