Scenario:
This code is a web service that receives an xml-serialized version of
an object that was previously fetched from the database in another
app. Based on reading "Java Persistence with Hibernate" page 413,
paragraph 3, I assumed that I could update an existing database object
by creating a transient copy and then executing a merge(). According
to the book, "If there is no equal persitent instance in the persistence
context, Hibernate loads it from the database". Based on the log, it
looks like
1) Hibernate is trying to insert a new row
2) It's failing when trying to set the version number
Hibernate version: 3.2.2
Log Excerpt:
Code:
DEBUG [03-01-2007 17:56:17] (SessionFactoryImpl.java:<init>:308) - instantiated session factory
DEBUG [03-01-2007 17:56:17] (SessionFactoryImpl.java:<init>:324) - obtaining JTA TransactionManager
INFO [03-01-2007 17:56:17] (NamingHelper.java:getInitialContext:26) - JNDI InitialContext properties:{}
DEBUG [03-01-2007 17:56:17] (SessionFactoryImpl.java:checkNamedQueries:392) - Checking 0 named HQL queries
DEBUG [03-01-2007 17:56:17] (SessionFactoryImpl.java:checkNamedQueries:412) - Checking 0 named SQL queries
DEBUG [03-01-2007 17:56:17] (SessionImpl.java:<init>:220) - opened session at timestamp: 11727933778
DEBUG [03-01-2007 17:56:17] (UpdateTeam.java:update:26) - got session
INFO [03-01-2007 17:56:17] (HibernateUtil.java:getUserTransaction:39) - Getting User Transaction
DEBUG [03-01-2007 17:56:17] (UpdateTeam.java:update:29) - got transaction
DEBUG [03-01-2007 17:56:17] (UpdateTeam.java:update:32) - starting merge
DEBUG [03-01-2007 17:56:17] (JDBCContext.java:registerSynchronizationIfPossible:172) - successfully registered Synchronization
DEBUG [03-01-2007 17:56:17] (VersionValue.java:isUnsaved:28) - version unsaved-value strategy NULL
DEBUG [03-01-2007 17:56:17] (AbstractSaveEventListener.java:getEntityState:514) - transient instance of: com.wholefoods.ittoolkit.ws.admin.Team
DEBUG [03-01-2007 17:56:17] (DefaultMergeEventListener.java:entityIsTransient:160) - merging transient instance
DEBUG [03-01-2007 17:56:17] (AbstractBatcher.java:logOpenPreparedStatement:358) - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG [03-01-2007 17:56:17] (ConnectionManager.java:openConnection:419) - opening JDBC connection
DEBUG [03-01-2007 17:56:18] (AbstractBatcher.java:log:393) - select ittoolkit.CR_TEAM_ID.nextval from dual
DEBUG [03-01-2007 17:56:18] (AbstractBatcher.java:getPreparedStatement:476) - preparing statement
DEBUG [03-01-2007 17:56:18] (SequenceGenerator.java:generate:82) - Sequence identifier generated: 3
DEBUG [03-01-2007 17:56:18] (AbstractBatcher.java:logClosePreparedStatement:366) - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG [03-01-2007 17:56:18] (AbstractBatcher.java:closePreparedStatement:525) - closing statement
DEBUG [03-01-2007 17:56:18] (ConnectionManager.java:aggressiveRelease:402) - aggressively releasing JDBC connection
DEBUG [03-01-2007 17:56:18] (ConnectionManager.java:closeConnection:439) - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
DEBUG [03-01-2007 17:56:18] (AbstractSaveEventListener.java:saveWithGeneratedId:112) - generated identifier: 3, using strategy: org.hibernate.id.SequenceGenerator
DEBUG [03-01-2007 17:56:18] (AbstractSaveEventListener.java:performSave:153) - saving [com.wholefoods.ittoolkit.ws.admin.Team#3]
DEBUG [03-01-2007 17:56:18] (Versioning.java:seed:56) - Seeding: 0
ERROR [03-01-2007 17:56:18] (UpdateTeam.java:update:41) - Exception
Mapping documents: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">
<hibernate-mapping package="com.wholefoods.ittoolkit.ws.admin">
<class name="Team" table="CR_TEAM">
<id name="id" column="TEAM_ID">
<generator class="sequence">
<param name="sequence">CR_TEAM_ID</param>
</generator>
</id>
<version name="version" access="field" column="VERSION" unsaved-value="null"/>
<property name="name" column="NAME"/>
<property name="email" column="EMAIL"/>
<property name="remedyGroupId" column="RMDY_GROUP_ID"/>
<set name="members" table="CR_TEAM_MEMBER">
<key column="TEAM_ID"/>
<composite-element class="TeamMember">
<property name="name" column="NAME" not-null="true"/>
<property name="email" column="EMAIL" not-null="true"/>
<property name="userId" column="USER_ID" not-null="true"/>
<property name="roleId" column="ROLE_IE" not-null="true"/>
</composite-element>
</set>
<idbag name="projects" table="CR_PROJECT" order-by="PROJECT_NAME asc">
<collection-id type="long" column="PROJECT_ID">
<generator class="sequence">
<param name="sequence">CR_PROJECT_ID</param>
</generator>
</collection-id>
<key column="TEAM_ID"/>
<composite-element class="TeamProject">
<property name="name" column="NAME" not-null="true"/>
</composite-element>
</idbag>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
Team t = new TeamParser().parse(new StringReader(xml));
log.debug(t);
Session session = HibernateUtil.getSessionFactory().openSession();
log.debug("got session");
tx = HibernateUtil.getUserTransaction();
log.debug("got transaction");
tx.begin();
log.debug("starting merge");
session.merge(t);
log.debug("merge successful");
tx.commit();
session.close();
Full stack trace of any exception that occurs:Code:
org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.wholefoods.ittoolkit.ws.admin.Team.version
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:82)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:337)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:200)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3560)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:277)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
at com.wholefoods.ittoolkit.ws.admin.UpdateTeam.update(UpdateTeam.java:33)
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:324)
at weblogic.webservice.component.javaclass.JavaClassInvocationHandler.invoke(JavaClassInvocationHandler.java:133)
at weblogic.webservice.core.handler.InvokeHandler.handleRequest(InvokeHandler.java:104)
at weblogic.webservice.core.HandlerChainImpl.handleRequest(HandlerChainImpl.java:143)
at weblogic.webservice.core.DefaultOperation.process(DefaultOperation.java:549)
at weblogic.webservice.server.Dispatcher.process(Dispatcher.java:204)
at weblogic.webservice.server.Dispatcher.doDispatch(Dispatcher.java:176)
at weblogic.webservice.server.Dispatcher.dispatch(Dispatcher.java:96)
at weblogic.webservice.server.WebServiceManager.dispatch(WebServiceManager.java:100)
at weblogic.webservice.server.servlet.WebServiceServlet.serverSideInvoke(WebServiceServlet.java:297)
at weblogic.webservice.server.servlet.ServletBase.doPost(ServletBase.java:498)
at weblogic.webservice.server.servlet.WebServiceServlet.doPost(WebServiceServlet.java:267)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7047)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2773)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
Caused by: java.lang.IllegalArgumentException
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
at java.lang.reflect.Field.set(Field.java:519)
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:79)
... 40 more
Name and version of the database you are using: Oracle9