Spring/Hibernate:保存后是不是必须加载实体才能使用它?
Posted
技术标签:
【中文标题】Spring/Hibernate:保存后是不是必须加载实体才能使用它?【英文标题】:Spring/Hibernate: Do you have to load entities to use it after saving?Spring/Hibernate:保存后是否必须加载实体才能使用它? 【发布时间】:2010-09-01 07:53:07 【问题描述】:我有一个包含两个表的数据库模型: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】:我能够解决问题: 表示实体中的 id 并在数据库模式中设置为自动递增的 @Id 注释属性也必须使用 @GeneratedValue 进行注释,例如
@Id
@GeneratedValue
private int id;
而不仅仅是。
@Id
private int id;
【讨论】:
你应该知道,这只有两天时间。以上是关于Spring/Hibernate:保存后是不是必须加载实体才能使用它?的主要内容,如果未能解决你的问题,请参考以下文章
Spring/Hibernate GenerationType.AUTO 的数据库备份问题
atitit.spring hibernate的事务机制 spring不能保存对象的解决
使用一对多映射保存对象时出现 Spring + Hibernate id 问题