Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
Hello,
I have searched for an answer to this problem and worked on it for 2 days. I know I am doing something wrong, but can't figure it out so far.
I created a manager object, which is a subclass of an employee object. To implement this subclass relationship I used a discriminator column in the employee table. I also have an EmployeeName object which has a primary key association with Employee.
This is a legacy app, and I have no idea why the employee name is in a seperate table. Since it is a legacy app, the values of the primary keys in the employee and the employee name table must stay the same.
I need to make an Employee a Manager. I created a constructor in the Manager class that accepts an Employee. In the constructor I set all the attributes of the manager with the same values of the employee class including the id since it needs to stay the same.
I then delete the employee object.
The manager object now contains the employeeName object. To tell hibernate that the employeeName object needs to be persisted, I set its id attribute to -1. Thats where I get the error listed below.
I also have attributes of employee that are collections. When I apply them to the mgr object do I have to iterate the entire collection to tell hibernate to save each object?
Hope this makes sense
Hibernate version:
2.1
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.1
http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->
<class
name="com.knight.model.Employee"
table="EMPLOYEE"
discriminator-value="EMP"
>
<meta attribute="implement-equals" inherit="false">true</meta>
<meta attribute="session-method">HibernateUtil.getSession();</meta>
<id
name="id"
type="java.lang.Long"
column="EMPID"
>
<meta attribute="finder-method">findById</meta>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
<generator class="assigned"/>
</id>
<discriminator column="EMP_TYPE" type="string"/>
<property
name="gender"
type="java.lang.String"
column="GENDER"
length="1"
>
<meta attribute="finder-method">findByGender</meta>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
</property>
<property
name="birthDt"
type="java.sql.Date"
column="BIRTHDT"
length="7"
>
<meta attribute="finder-method">findByBirthDate</meta>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
</property>
<property
name="ssn"
type="java.lang.String"
column="SSN"
length="9"
>
<meta attribute="finder-method">findBySsn</meta>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
</property>
<property
name="adpFileNum"
type="java.lang.String"
column="ADPFILENUM"
length="8"
>
<meta attribute="finder-method">findByAdpFileNum</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="comments"
type="java.lang.String"
column="COMMENTS"
length="40"
/>
<property
name="userId"
type="java.lang.Long"
column="USERID"
length="4"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="moddt"
type="java.sql.Date"
column="MODDT"
length="7"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="mclaglanCode"
type="java.lang.String"
column="MCLAG"
length="9"
>
<meta attribute="finder-method">findByMclaglanCode</meta>
</property>
<property
name="producer"
type="java.lang.String"
column="PRODUCER"
length="1"
>
<meta attribute="finder-method">findByProducer</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="hireDate"
type="java.sql.Date"
column="HIREDT"
length="7"
>
<meta attribute="finder-method">findByHireDate</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="company"
type="java.lang.String"
column="COMPANY"
length="5"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="costcenter"
type="java.lang.String"
column="COSTCENTER"
length="60"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="corporateTitleDescr"
type="java.lang.String"
column="CORPTITLE"
length="50"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="functionalTitle"
type="java.lang.String"
column="FUNCTITLE"
length="60"
>
<meta attribute="finder-method">findByFunctionalTitle</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="location"
type="java.lang.String"
column="LOCATION"
length="30"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="status"
type="java.lang.String"
column="STATUS"
length="20"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="termDate"
type="java.sql.Date"
column="TERMDT"
length="7"
>
<meta attribute="finder-method">findByTermDate</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="costCenterId"
type="java.lang.String"
column="COSTCTR"
length="6"
>
<meta attribute="finder-method">findByCostCenterId</meta>
</property>
<property
name="locationId"
type="java.lang.String"
column="LOCODE"
length="3"
>
<meta attribute="finder-method">findByLocationId</meta>
</property>
<property
name="companyCode"
type="java.lang.String"
column="COMPCODE"
length="4"
>
<meta attribute="finder-method">findByCompanyCode</meta>
</property>
<property
name="employmentStatus"
type="java.lang.String"
column="STAT"
length="1"
>
<meta attribute="finder-method">findByEmploymentStatus</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="intlStatus"
type="java.lang.String"
column="INTLSTATUS"
length="25"
>
<meta attribute="finder-method">findByInternationalStatus</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="category"
type="java.lang.String"
column="CATEGORY"
length="25"
>
<meta attribute="finder-method">findByCategory</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="corpTitleCode"
type="java.lang.String"
column="CTITLECODE"
length="15"
>
<meta attribute="finder-method">findByCorporateTitle</meta>
</property>
<property
name="registered"
type="java.lang.String"
column="REGISTERED"
length="1"
>
<meta attribute="finder-method">findByRegistered</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="hAndDTraining"
type="java.lang.String"
column="HANDTRNG"
length="1"
>
<meta attribute="finder-method">findByHAndDTraining</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="benefitTier"
type="java.lang.Integer"
column="BENEFITTIER"
length="2"
>
<meta attribute="finder-method">findByBenefitTier</meta>
<meta attribute="use-in-tostring">true</meta>
</property>
<!-- Associations -->
<!-- bi-directional one-to-many association to EmployeeCompensation -->
<set
name="employeeCompensations"
lazy="true"
inverse="true"
cascade="all"
>
<key>
<column name="EMPID"/>
</key>
<one-to-many
class="com.knight.model.EmployeeCompensation"
/>
</set>
<!-- uni-directional one-to-many association to EmployeeActivity -->
<set
name="employeeActivities"
lazy="true"
inverse="true"
cascade="all"
>
<key>
<column name="EMPID"/>
</key>
<one-to-many
class="com.knight.model.EmployeeActivity"
/>
</set>
<!-- bi-directional one-to-one association to EmployeeName -->
<one-to-one
name="employeeName"
class="com.knight.model.EmployeeName"
cascade="all"
outer-join="auto"
/>
<!-- bi-directional many-to-one association to Manager -->
<many-to-one
name="manager"
class="com.knight.model.Manager"
not-null="true"
>
<meta attribute="use-in-equals">true</meta>
<column name="MGR_ID"/>
</many-to-one>
<!-- uni-directional many-to-one association to Lookup -->
<many-to-one
name="lookupByEeoCode"
class="com.knight.model.Lookup"
>
<meta attribute="finder-method">findByEeoCode</meta>
<column name="EEOCODE"/>
</many-to-one>
<!-- uni-directional many-to-one association to Lookup -->
<many-to-one
name="lookupByMaritalStatus"
class="com.knight.model.Lookup"
>
<meta attribute="finder-method">findByMaritalStatus</meta>
<column name="MARITALSTAT"/>
</many-to-one>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.1
http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->
<class
name="com.knight.model.EmployeeName"
table="EMPLOYEE_NAME"
>
<meta attribute="implement-equals" inherit="false">true</meta>
<meta attribute="session-method">HibernateUtil.getSession();</meta>
<id
name="id"
type="java.lang.Long"
column="EMPID"
unsaved-value="-1"
>
<meta attribute="finder-method">findById</meta>
<meta attribute="use-in-equals">true</meta>
<generator class="foreign">
<param name="property">employee</param>
</generator>
</id>
<property
name="lname"
type="java.lang.String"
column="LNAME"
length="40"
>
<meta attribute="finder-method">findByLastName</meta>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
</property>
<property
name="fname"
type="java.lang.String"
column="FNAME"
length="40"
>
<meta attribute="finder-method">findByFirstName</meta>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
</property>
<property
name="mname"
type="java.lang.String"
column="MNAME"
length="25"
>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
</property>
<property
name="maidename"
type="java.lang.String"
column="MAIDENAME"
length="70"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="goesby"
type="java.lang.String"
column="GOESBY"
length="70"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="userid"
type="java.lang.Long"
column="USERID"
length="4"
/>
<property
name="moddt"
type="java.sql.Date"
column="MODDT"
length="7"
/>
<!-- Associations -->
<!-- bi-directional one-to-one association to Employee -->
<one-to-one
name="employee"
class="com.knight.model.Employee"
outer-join="auto"
constrained="true"
/>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.1
http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->
<subclass
name="com.knight.model.Manager"
discriminator-value="MGR"
extends="com.knight.model.Employee"
>
<meta attribute="implement-equals" inherit="false">true</meta>
<meta attribute="session-method"> HibernateUtil.getSession();</meta>
<!-- Associations -->
<!-- bi-directional one-to-many association to Employee -->
<set
name="employees"
lazy="true"
inverse="true"
cascade="none"
>
<key>
<column name="MGR_ID"/>
</key>
<one-to-many
class="com.knight.model.Employee"
/>
</set>
</subclass>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
HibernateUtil.beginTransaction();
List employees = EmployeeFinder.findById(new Long(employeesSubmitted[i]));
Employee employee = (Employee) employees.get(0);
Manager manager = new Manager(employee);
manager.getEmployeeName().setId(new Long(-1));
HibernateUtil.getSession().delete(employee);
HibernateUtil.getSession().save(manager);
HibernateUtil.commitTransaction();
Full stack trace of any exception that occurs:
net.sf.hibernate.HibernateException: identifier of an instance of com.knight.model.EmployeeName altered from 3030 to -1
at net.sf.hibernate.impl.SessionImpl.checkId(SessionImpl.java:2670)
at net.sf.hibernate.impl.SessionImpl.flushEntity(SessionImpl.java:2493)
at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2486)
at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2281)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2260)
at net.sf.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:769)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:849)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:790)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:749)
at com.knight.empHierarchy.AddReplaceMgrServlet.doPost(AddReplaceMgrServlet.java:68)
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:1006)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:419)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:315)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:6718)
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:3764)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2644)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:219)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:178)
Name and version of the database you are using:
Oracle 9i
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt: