我正在使用带有hibernate的spring,当我尝试插入已经存在的数据时,它会抛出DataIntegrityViolationException。 因此,为了处理这个异常,我在DAO层的save方法中放置了一个try / catch块,但它没有被捕获。 之后我在服务层的保存方法中放置了一个try / catch块,但也没有被捕获。
我的服务层中有一个testMain方法,当我在那里处理时,它会被抓到那里。
请帮助我在DAO图层中处理这个问题
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext applicationContext = SpringUtil
.getApplicationContextInstance();
UserDaoService userDaoService = applicationContext.getBean("userDaoService",
UserDaoService.class);
UserDaoImpl userDao = applicationContext.getBean("userDaoImpl",
UserDaoImpl.class);
User user = new User();
user.setActive(true);
user.setEmail("shariquealam01@gmail.com");
user.setFirstName("Md");
user.setMiddleName("Sharique");
user.setLastName("Alam");
user.setId(1);
user.setPassword("123");
user.setUserName("shariquealam01");
userDaoService.saveUser(user);
}
}
@服务
public class UserDaoService {
@Autowired
public UserDao userDao;
@Transactional
public void saveUser(User user){
System.out.println("User Saving");
/*user.setActive(true);
user.setEmail("shariquealam06@gmail.com");
user.setFirstName("Md");
user.setMiddleName("Sharique");
user.setLastName("Alam");
user.setId(6);
user.setPassword("123");
user.setUserName("shariquealam06");*/
userDao.saveUser(user) ;
/*try{
System.out.println("Inside Service Try");
userDao.saveUser(user);
} catch (Exception e){
System.out.println("Exception Occured "+e);
}*/
// deleteUser(3);
}
}
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private SessionFactory sessionFactory;
public Role getRole(int id){
Session session = getSessionFactory().getCurrentSession();
Role role = (Role) session.get(Role.class, id);
return role;
}
@Override
public void saveUser(User user) {
// Session session = getSessionFactory().getCurrentSession();
/*role.setRoleId(102);
role.setRoleName("User");*/
// role.getUsers().add(user);
/*session.save(user);*/
//logger.info( "Executing Query to ADD User"); //Since this query is important for the state of application, have info logging
Role role = getRole(102);
user.getRoles().add(role);
Session session = sessionFactory.getCurrentSession();
session.save( user );
//userId = user.getId();
//logger.info( "User ADDED to DB with userId as {}", user.getId() );
//session.save(role);
}
}
Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:163)
at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:730)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:592)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:515)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.sharique.service.UserDaoService$$EnhancerBySpringCGLIB$$956522ab.saveUser(<generated>)
at com.sharique.main.TestMain.main(TestMain.java:40)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:129)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3124)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3581)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
... 9 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Violation of PRIMARY KEY constraint 'PK__USER_DET__F3BEEBFF77DFC722'. Cannot insert duplicate key in object 'dbo.USER_DETAILS'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:314)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
... 22 more
答案 0 :(得分:1)
当您调用persist()
或save()
时,不会出现堆栈跟踪应显示的异常。它在调用flush()
时发生,即实际执行SQL插入语句时。并且在事务提交之前自动调用flush()
。
你可以明确地调用flush()
并捕获异常,但这将是无用的,因为Hibernate异常是不可恢复的。他们让会话处于无法使用的状态。面对这样的异常时唯一安全的做法是回滚事务并关闭会话。
做正确的事情:在尝试插入之前,使用自动生成的主键和/或使用查询检查数据是否不存在。