Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data - Cannot catch DataIntegrityViolationException in Service Layer

I am using a org.springframework.data.jpa.repository.JpaRepository save method to save an entity. I figure that save method comes from CrudRepository interface. I am calling this save method from a service class.

try {
    studentLog = studentsLogRepository.save(studentLog);        
} catch (DataIntegrityViolationException dive) {
    LOGGER.warn("Constraint violation occurred. Cannot insert the same record twice.", dive);
}

But the problem is DataIntegrityViolationException is not getting caugh in the catch block. Instead I see in the log following.

java.sql.BatchUpdateException: ORA-00001: unique constraint (QA_VPP.UX_TVPPC_TRAN_LOG_1) violated
        at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10296) ~[ojdbc6-11.2.0.2.0.jar:11.2.0.2.0]
        at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:216) ~[ojdbc6-11.2.0.2.0.jar:11.2.0.2.0]
        at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297) ~[commons-dbcp-1.3.jar:1.3]
        at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297) ~[commons-dbcp-1.3.jar:1.3]
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) ~[hibernate-core-3.6.7.Final.jar:3.6.7.Final]...

and

2016-12-28 10:13:52,655 LL="DEBUG" CR="1_1482920032_407_357_l73q069_VPP" RE="1482920032407" DE="1" TR="tomcat-http--12" LN="o.s.o.j.JpaTransactionManager"  Initiating transaction rollback after commit exception
org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
        at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:321) ~[spring-orm-3.2.9.RELEASE.jar:3.2.9.RELEASE]
        at org.springframework.orm.jpa.DefaultJpaDialect.translateExceptionIfPossible(DefaultJpaDialect.java:121) ~[spring-orm-3.2.9.RELEASE.jar:3.2.9.RELEASE]
        at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) ~[spring-orm-3.2.9.RELEASE.jar:3.2.9.RELEASE]
        at 

I even tried catching ConstraintViolationException which did not work. I thought spring data wraps data layer exception to DataAccessException, in this case its subclass DataIntegrityViolationException. Then why is the exception is not getting caught? My service method is not annotated with @Transactional

like image 383
TV Nath Avatar asked Jul 05 '26 16:07

TV Nath


2 Answers

What is happening is that when calling the method .save(), under the hood Spring is telling the EntityManager to persist the entity, which will be only making it managed and persistent within the persistence context, however changes in your entity may not be immediately synchronized with the DB state (depending on the flush mode of your configuration), so either exceptions are not thrown yet, until flush or commit commands are issued. So you can try to call .saveAndFlush() to enforce DB synchronization. This way exceptions will be thrown immediately.

To further comprehend how Spring handles transaction management, I'll leave a useful link: Transaction Management

like image 78
darkconeja Avatar answered Jul 07 '26 06:07

darkconeja


exception thrown from Spring exception translation mechanism when dealing with lower level persistence exceptions. so untill the transaction commits not done , so need to catch outside the scope

Example TODO Service Class

studentLog = studentsLogRepository.save(studentLog);        

Catch at controller class
try {
    call student service     
} catch (DataIntegrityViolationException dive) {
    LOGGER.warn("Constraint violation occurred. Cannot insert the same record twice.", dive);

or Use Global Exception Handler to do the same using controller advice

like image 21
user1388547 Avatar answered Jul 07 '26 05:07

user1388547



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!