好的,这有点棘手,但我会尽力而为。Hibernate仅在使用@Transactional注释的方法退出时才提交事务。因此,只有在该方法返回后,您的DataIntegrityViolationException才能被捕获。您无法让Hibernate不调用,UserDAO2.save()
因为它无法检测到已发生违规。我将在下面提供一个示例
@Service
/*These variable names are used for clarity's sake, I don't actually use these names myself*/
public UserServiceImpl implements UserService{
@Autowired
private HibernateUserDAO1 userDao1;
@Autowired
private HibernateUserDAO2 userDao2
@Transactional
/*Put your try catch block around where this method is called*/
public void saveUserDao1(User user){
userDao1.saveOrUpdate(user);
}
@Transactional
/*Only call this if saveUserDao1 succeeds*/
public void saveUserDao2(User user){
userDao2.saveOrUpdate(user)
}
}
然后在您的HibernateUserDAO1中:
public void saveOrUpdate(User user){
currentSession().saveOrUpdate(user);
}
只能在服务层之上捕获异常。理想情况下,您要执行的操作是使用两个不同的DAO进行个人保存,并在执行第二个操作之前检查第一个操作是否成功。
编辑:还请注意,Hibernate将不会使用@Transactional注释的私有方法,因为Hibernate依赖于从类实现的接口创建Proxy对象。没有接口定义=没有代理对象=没有hibernate会话。因此,您不能调用带有@Transactional注释的私有方法。我将尝试使您的SessionFactory成为抽象超类中的对象,并让DAO都继承自此。更好的选择是使用2个事务管理器,每个事务管理器都指向您的不同数据库,然后指定要保存的数据库内容。这样,您可以只使用1个DAO,并使用进行保存所需的任何会话工厂。