views:

74

answers:

1

Hi all,

I have a database model with two tables: Session and ScriptExecution which are associated with a one-to-many relationship:

public class ScriptExecution implements Serializable {

 @ManyToOne
 @PrimaryKeyJoinColumn
 private Session session;

...
}

public class Session implements Serializable {

 @OneToMany(fetch=FetchType.EAGER, mappedBy="session")
 private Set<ScriptExecution> scriptExecutions;

...
}

If I create a session, load it and assign it to a script execution everything works fine:

Session session = new Session();
sessionDao.save(session);

session = sessionDao.load(1);

ScriptExecution scriptExecution = new ScriptExecution();
ScriptExecution.setSession(session);
scriptExecutionDao.save(scriptExecution);

If I use the created session directly to assign it to the ScriptExecution as follows:

Session session = new Session();
sessionDao.save(session);

ScriptExecution scriptExecution = new ScriptExecution();
ScriptExecution.setSession(session);
scriptExecutionDao.save(scriptExecution);

Hibernate fails with the following error:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into script_execution (end, session_id, start, id) values (?, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

root cause

org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into script_execution (end, session_id, start, id) values (?, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
 org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:637)
 org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
 org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
 org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147)
 com.sc2.web.controller.MainController.handleRequest(MainController.java:45)
 org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:774)
 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

root cause

org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
 org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
 org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
 org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
 org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
 org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
 org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
 org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
 org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
 org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
 org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
 org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
 org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147)
 com.sc2.web.controller.MainController.handleRequest(MainController.java:45)
 org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:774)
 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

root cause

java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`sc2`.`script_execution`, CONSTRAINT `fk_script_execution_session1` FOREIGN KEY (`session_id`) REFERENCES `session` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
 com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2020)
 com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1451)
 org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
 org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
 org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
 org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
 org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
 org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
 org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
 org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
 org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
 org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
 org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147)
 com.sc2.web.controller.MainController.handleRequest(MainController.java:45)
 org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:774)
 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

I have also tried to put the code in a transaction, but the code fails with the same error.

TransactionTemplate template = new TransactionTemplate(transactionManager);
template.execute(new TransactionCallbackWithoutResult() {

   @Override
   protected void doInTransactionWithoutResult(TransactionStatus arg0) {
    Session session = new Session();
    sessionDao.save(session);

    ScriptExecution scriptExecution = new ScriptExecution();
    scriptExecution.setSession(session);
    scriptExecutionDao.save(scriptExecution);

   }
  });

Do you have any ideas what's wrong? I can't believe I have to load created entities after creating them.

+2  A: 

I was able to solve the problem: The @Id annotated properties that represent the id's in your entities and are set to auto-increment in your database schema have to be annotated with @GeneratedValue too, e.g.

@Id
@GeneratedValue
private int id;

instead of only.

@Id
private int id;
Heinrich
Then you should accept your own answer
Shervin
You should know that this is only possible in two days.
Heinrich