2012-10-09 118 views
0

我有实体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并检查是否类似项目,我试图添加的是数据库。但是这需要从数据库中进行额外的选择,我对此有点担心。

回答

1

这就是实际的SQLState。

做这样的事情

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

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

一个链接,我发现了ISO的SQLStates,

link to reference

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

+0

在我的情况下,HibernateException将被Spring包装,但我猜SQLState是我正在寻找的。 –

0

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

从我的角度来看,你应该做选择/寻找最前沿。请记住,您正在使用ORM! Hibernate包含缓存,所以select/find和key constraint错误都不是实际的db查询的结果,而是基于已经载入缓存的数据计算Hibernate的结果。

塞巴斯蒂安

+0

我不完全知道如何做select/find upfront解决我的问题。我的应用程序的其他一些线程/节点仍然可以在选择和插入之间插入冲突实体。 –

0

捕获org.hibernate.JDBCException。这有getErrorCode()。对于独特的约束voilation它的ORA-00001。

-Maddy

+0

ORA-00001是否与Oracle相关? –

0

如果有数据库异常,它将被捕获到HibernateException,这是一个检查异常。 Spring将其包含在DataAccessException中,该选项未被选中。这个例外将运行到您的Controller并输出到Servlet,并最终以浏览器和日志文件中的堆栈跟踪结束。您可以捕获此异常并将其打印出来,以便查看正在发生的情况。这至少会让你知道什么是真正的突破。

坏钥匙可能是一个问题。但不好的价值可能是另一回事。一些非空字段为空,或者某些东西不够长或足够短等。修复这可能涉及验证。您可以使用Hibernate Validator。你给你的领域一些漂亮的注释,然后你在得到数据库之前就会得到java验证错误 - 错误发生得更快。