Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 数据库约束冲突未在Hibernate中引发异常_Java_Spring_Hibernate_Jpa - Fatal编程技术网

Java 数据库约束冲突未在Hibernate中引发异常

Java 数据库约束冲突未在Hibernate中引发异常,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我有以下代码: try { userDAO1.save(userRecord); userDAO2.save(userRecord); } catch(DataIntegrityViolationException e) { throw new ApplicationException("Contraint violated") } save(userRecord)违反了完整性约束,因此在整个代码运行之后,就不会向userDAO1引用的表写入任何内容 但是,userDA

我有以下代码:

try {
    userDAO1.save(userRecord);
    userDAO2.save(userRecord);
}
catch(DataIntegrityViolationException e) {
    throw new ApplicationException("Contraint violated")
}
save(userRecord)违反了完整性约束,因此在整个代码运行之后,就不会向userDAO1引用的表写入任何内容

但是,userDAO1.save()语句不会引发错误/异常,因此也会执行userDAO2.save()

但是DataIntegrityViolationException被捕获,并且堆栈跟踪为null

如何检查DataIntegrityViolationException从何处抛出,并在userDAO1.save()违反约束时防止执行userDAO2.save()

我尝试在这段代码周围添加@Transactional注释,但也没有成功

堆栈跟踪:

org.springframework.dao.DataIntegrityViolationException: ORA-00001: unique constraint (UNIQUE_EMAIL) violated
; SQL [n/a]; constraint [UNIQUE_EMAIL]; nested exception is org.hibernate.exception.ConstraintViolationException: ORA-00001: unique constraint (UNIQUE_EMAIL) violated

    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:643)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:104)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:516)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at com.sun.proxy.$Proxy76.updateUser(Unknown Source)
    at com.osiris.UserReg.UpdateUserCommand.execute(UpdateUserCommand.java:63)

我发布的代码在UpdateUserCommand中,它用
@Transactional(rollboor=Exception.class,propagation=propagation.REQUIRES\u NEW)注释

是什么让您相信在执行语句userDAO1.save()时没有抛出DataIntegrityViolationException?另外,为什么您认为语句userDAO2.save()也被执行了

如果上述观点是在IDE调试控制台(如Eclipse)中对代码执行进度进行观察后得出的,那么解释可能是错误的

请尝试通过插入一些调试语句(如下面的语句)并执行代码来观察结果。这可能有助于您找出故障的根本原因-

try {
    userDAO1.save(userRecord);
    System.out.println("-- After userDAO1.save(userRecord) --");
    userDAO2.save(userRecord);
    System.out.println("-- After userDAO2.save(userRecord) --");
} catch(DataIntegrityViolationException e) {
    e.printStackTrace();
    throw new ApplicationException("Contraint violated")
}

是什么让您相信在执行语句userDAO1.save()时没有抛出DataIntegrityViolationException?另外,为什么您认为语句userDAO2.save()也被执行了

如果上述观点是在IDE调试控制台(如Eclipse)中对代码执行进度进行观察后得出的,那么解释可能是错误的

请尝试通过插入一些调试语句(如下面的语句)并执行代码来观察结果。这可能有助于您找出故障的根本原因-

try {
    userDAO1.save(userRecord);
    System.out.println("-- After userDAO1.save(userRecord) --");
    userDAO2.save(userRecord);
    System.out.println("-- After userDAO2.save(userRecord) --");
} catch(DataIntegrityViolationException e) {
    e.printStackTrace();
    throw new ApplicationException("Contraint violated")
}

好吧,这有点棘手,但我会尽力的。 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进行单独保存,并在执行第二个DAO之前检查第一个DAO是否成功

编辑:
还请注意,Hibernate不会选择带有@Transactional注释的私有方法,因为Hibernate依赖于从类实现的接口创建代理对象。无接口定义=无代理对象=无休眠会话。因此,您不能调用带有@Transactional注释的私有方法。我将尝试使您的SessionFactory成为抽象超类中的对象,并使两个DAO都继承自此。更好的选择是使用两个事务管理器,每个事务管理器指向不同的数据库,然后指定要保存的数据库。这样,您可以只使用1个DAO,并使用您需要的任何会话工厂进行保存。

好的,这有点棘手,但我会尽全力。 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进行单独保存,并在执行第二个DAO之前检查第一个DAO是否成功

编辑:
还请注意,Hibernate不会选择带有@Transactional注释的私有方法,因为Hibernate依赖于从类实现的接口创建代理对象。无接口定义=无代理对象=无休眠会话。因此,您不能调用带有@Transactional注释的私有方法。我将尝试使您的SessionFactory成为抽象超类中的对象,并使两个DAO都继承自此。更好的选择是使用两个事务管理器,每个事务管理器指向不同的数据库,然后指定要保存的数据库。这样,您可以只使用1个DAO,并使用您需要的任何会话工厂进行保存。

请阅读save()或persist()或merge()的javadoc或DAO.save()方法中调用的任何内容。调用此方法时,它不会告诉您是否执行了插入查询。我非常怀疑堆栈跟踪是否为空。将
e.printStackTrace()
添加到catch块,您将看到它。并将DataIntegrityViolationException包装在您的ApplicationException中。与应答无关,但您是否正在服务层捕获
DataIntegrityViolationException
exception?,查看您的代码,您似乎正在这样做。这不是个好主意。服务层与Dao层异常无关。出于发布目的,我简化了代码-有一个单独的业务层@Nizet-我添加了一个printStackStrace(),提到的唯一类是内部spring类-我没有写任何东西。请阅读save()或persist()或merge()的javadoc或DAO.save()方法中调用的任何内容。调用此方法时,它不会告诉您是否执行了插入查询。我非常怀疑堆栈跟踪是否为空。将
e.printStackTrace()
添加到catch块,您将看到它。包装