Spring / Hibernate: вам нужно загружать объекты, чтобы использовать его после сохранения? - PullRequest
2 голосов
/ 01 сентября 2010

У меня есть модель базы данных с двумя таблицами: Session и ScriptExecution, которые связаны с отношением «один ко многим»:

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;

...
}

Если я создаю сеанс, загружаю его и назначаю для выполнения скрипта, все работает нормально:

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

session = sessionDao.load(1);

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

Если я использую созданный сеанс напрямую, чтобы назначить его для ScriptExecution следующим образом:

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

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

Hibernate завершается со следующей ошибкой:

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)

Я также пытался ввести код в транзакцию, но код завершился неудачно с той же ошибкой.

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);

   }
  });

У вас есть идеи, что случилось? Я не могу поверить, что мне нужно загружать созданные объекты после их создания.

1 Ответ

2 голосов
/ 01 сентября 2010

Мне удалось решить проблему: аннотированные свойства @Id, которые представляют идентификаторы в ваших сущностях и имеют автоматическое приращение в схеме базы данных, также должны быть аннотированы @GeneratedValue, например

@Id
@GeneratedValue
private int id;

вместо только.

@Id
private int id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...