0

I suppose this must be a very basic question.

I relaunch this code which tries to insert an already existing row in a table but the ConstraintViolationException is catched in the general catch (Exception e) block insted of being catched in the specific catch (ConstraintViolationException e) block as I expected.

I wonder what should I try to catch that specific exception.

My code:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.exception.ConstraintViolationException;
import clases.Departamentos;
import util.HibernateUtil;
 
public class InsertarDepartamento {
 
    public static void main(String[] args) {
        //obtenemos la sesión actual
        SessionFactory sf = HibernateUtil.getSessionFactory();
        //creamos la sesión
        Session s = sf.openSession();
        Transaction tx = null;
                 
        try {
            //creamos una transacción en la sesión
            tx = s.beginTransaction();
            System.out.println("Vamos insertar una nueva fila en la tabla Departamentos");
            Departamentos dep = new Departamentos();
            dep.setNumero(3);
            dep.setNombre("Marketing");
             
            try {
                s.save(dep); //hacemos persistente el objeto departamento creado            
            } catch (ConstraintViolationException e) {
                System.err.println(e);
            }           
            tx.commit(); // javax.persistence.EntityTransaction;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            s.close();          
        }       
    }
 
}

My console output:

Vamos insertar una nueva fila en la tabla Departamentos nov 18, 2022 1:10:26 A. M. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN: SQL Error: 1062, SQLState: 23000 nov 18, 2022 1:10:26 A. M. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions ERROR: Duplicate entry '3' for key 'departamentos.PRIMARY' nov 18, 2022 1:10:26 A. M. org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release INFO: HHH000010: On release of batch it still contained JDBC statements org.hibernate.exception.ConstraintViolationException: could not execute statement

I am editting the question following some suggestions in the comments. I have seen two things:

  1. I was assuming it was the save method which launched the ConstraintViolationException but in fact it is the commit method which launches it
  2. I can catch PersistenceException (not ConstraintViolationException)

I wonder if this code would be acceptable:

import javax.persistence.PersistenceException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.exception.ConstraintViolationException;
import clases.Departamentos;
import util.HibernateUtil;

public class InsertarDepartamento {

    public static void main(String[] args) {
        //obtenemos la sesión actual
        SessionFactory sf = HibernateUtil.getSessionFactory();
        //creamos la sesión
        Session s = sf.openSession();
        Transaction tx = null;
                
        try {
            //creamos una transacción en la sesión
            tx = s.beginTransaction();
            System.out.println("Vamos insertar una nueva fila en la tabla Departamentos");
            Departamentos dep = new Departamentos();
            dep.setNumero(3);
            dep.setNombre("Marketing");
            
            try {
                s.save(dep); //hacemos persistente el objeto departamento creado
                tx.commit(); // javax.persistence.EntityTransaction;
            } catch (ConstraintViolationException e) {
                System.out.println("ConstraintViolationException: "+e.getMessage());
                //e.printStackTrace();
            } catch (PersistenceException e) {
                System.out.println("PersistenceException: "+e.getMessage());
                //e.printStackTrace();
            }           
        } catch (Exception e) {
            //System.out.println(e.getMessage());
            //System.out.println(e.getCause());
            //System.out.println(e.getStackTrace());
            e.printStackTrace();
        } finally {
            if (tx != null) {
                tx.rollback();
            }           
            s.close();          
        }       
    }

}

Which causes this new output:

Vamos insertar una nueva fila en la tabla Departamentos nov 18, 2022 9:54:59 A. M. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN: SQL Error: 1062, SQLState: 23000 nov 18, 2022 9:54:59 A. M. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions ERROR: Duplicate entry '3' for key 'departamentos.PRIMARY' nov 18, 2022 9:54:59 A. M. org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release INFO: HHH000010: On release of batch it still contained JDBC statements PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement

  • Instead of doing `System.out.println(e.getMessage())`, do `e.printStackTrace()`. From the stack trace, determine which line of _your code_ is actually throwing the exception. If it's anything other than the `s.save(dep)` call, then that is (at least part of) why you cannot catch the exception where you expect. – Slaw Nov 18 '22 at 02:41
  • Thanks. It was in fact the commit call which caused it. – errorrelativo Nov 18 '22 at 10:15

1 Answers1

0

It's wrapped by PersistenceException

You actually cannot catch the ConstraintViolationException since JPA will wrap it an a PersistenceException, but you can verify that a ConstraintViolationException caused the PersistenceException.

https://stackoverflow.com/questions/54876448/how-to-catch-hibernate-constraintviolationexception-or-spring-dataintegrityviol

evaluator screen

Lucas
  • 48
  • 9
  • No, I'm not using Spring. I have no idea what could be wrapping this exception – errorrelativo Nov 18 '22 at 01:14
  • You can set breakpoint inside exception catch block and then in debugger check what real exception has been thrown. – Lucas Nov 18 '22 at 01:18
  • This is what I see in the debugger: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement. I have tried to catch javax.persistence.PersistenceException instead but it fails again. – errorrelativo Nov 18 '22 at 01:29
  • You actually cannot catch the ConstraintViolationException since JPA will wrap it an a PersistenceException, but you can verify that a ConstraintViolationException caused the PersistenceException. https://stackoverflow.com/questions/54876448/how-to-catch-hibernate-constraintviolationexception-or-spring-dataintegrityviol – Lucas Nov 18 '22 at 01:35
  • Can you post your new code with catching `javax.persistence.PersistenceException` ? – Lucas Nov 18 '22 at 01:45
  • Did you figured it out? – Lucas Nov 23 '22 at 00:00