I have been very reluctant to post but this issue is bugging me and I am unable to find anyone who has encountered similar symptoms. I don't think this is a failure of understanding of how hibernate works, but I'll start with what I think is supposed to happen.
I am simply trying to do an insert into a stripped down two column database. The idea is game state data needs to be saved to the Game table. I've reduced it two two columns for test purposes. The ID key is intended to be a primary key (so no null values) and is typed as a Postgres Serial field. From what I understand (and observe) this means the field is of Integer type, and it's default value is generated from a complementary sequence. However, postgres sets the default value of the column to the next sequence value so hibernate doesn't have to know about the sequence. Since this sounds like identity generator, I've chosen that. (As an aside, when I tried to use the sequence generator, I got another error. I can visit that in another post if necessary. Picking one issue at a time.)
For some reason, it appears that hibernate is trying to insert null for the id on a new object that needs to be persisted for the first time. However, I've read the documentation and it seems as if Hibernate is supposed to handle all this automatically. I've read Java Persistence with Hibernate and it says this in Section 12. The hibernate docs also repeat this, explaining that unsaved-value attribute on ids should rarely have to be used anymore since hibernate does the detection on its own.
I had encountered this issue once before on a work project with a
property and set insert="false", however, that's not an option for ids. I also checked out dynamicInsert on the class but it doesn't help either. I've also set unsaved-value to null but this doesn't coerce hibernate into the right behavior either.
I'm missing something...
Thank you.
Hibernate version: According to the jar, 3.3.0.SP1
Mapping documents:
One:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Oct 6, 2008 10:16:50 PM by Hibernate Tools 3.2.0.beta8 -->
<hibernate-mapping>
<class name="package.Game" dynamic-insert="true" table="game">
<id name="id" type="java.lang.Integer">
<column name="id" not-null="true"></column>
<generator class="identity"></generator>
</id>
<property name="data" />
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():I am using Spring to provide my session via dependency injection into the HibernateTemplate class, which is injected into my DAO. I am coding a simple Struts 2 application with a DAO being injected into my action. So in my Action I have:
Code:
Game newGame = new Game();
newGame.setData(data);
engine.saveGame(newGame);
and engine.saveGame is where I use the HibernateTemplate class to saveOrUpdate
Code:
//In my engine object
public void saveGame(Game game){
hibernateTemplate.saveOrUpdate(game);
}
Full stack trace of any exception that occurs:Not completely full, eliminated late entries that are repetitive.
Code:
org.postgresql.util.PSQLException: ERROR: null value in column "id" violates not-null constraint
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1592)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1327)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:192)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:304)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:57)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2186)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2659)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:534)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:526)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:522)
at org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:747)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:744)
at MyDAOEngineImpl.saveGame(MyDAOEngineImple.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy5.saveGame(Unknown Source)
at MyPackage.manager.CreateGame.execute(CreateGame.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:404)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:267)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:229)
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:221)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
Name and version of the database you are using:
PostgreSQL 8.3.3
The generated SQL (show_sql=true):
Hibernate: insert into game (data, id) values (?, null)
Debug level Hibernate log excerpt:
Quote:
9272 [http-8080-Processor24] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 23502
9272 [http-8080-Processor24] ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: null value in column "id" violates not-null constraint