-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Problem with entity-name and self-reference
PostPosted: Mon Oct 23, 2006 10:46 am 
Newbie

Joined: Mon Oct 23, 2006 9:57 am
Posts: 2
Hi,

currently I have problem with a mapping and self-reference. My User class is mapped to two tables, so I used the entity-name feature. The first entity is for the current version, the other ist to keep historical data. Here's my class (stripped down):

Code:
public class User {
   private Long id;
   private Long historyId;
   private User modifiedBy;
   private Date modified;
   private Date effectiveStartDate;
   private Date effectiveEndDate;
   private User owner;
   private String loginName;
   private String loginPass;
   private Integer version;
        private List acls;
...
       
       getters + setters ...
}


Everything works fine (updates to CurrentUser, inserts to HistoricalUser) until I have a self-reference in 'modifiedBy' (or 'owner') which holds the reference to the user who made the last changes to the record. Hibernate 'thinks' it should make a reference to the entity 'HistoricalUser', although I specified it by entity-name=CurrentUser. This leads to an exception where the DB complains about a foreign-key violation.

My question: How do I tell hibernate to use the correct entity?

Hibernate version:
3.2.0ga

Mapping documents:
Code:
...
<hibernate-mapping package="model">
  <class name="User" table="users" entity-name="CurrentUser">
  <id unsaved-value="null" name="id" column="id" type="java.lang.Long">
      <generator class="native"></generator>
    </id>
    <version name="version" column="version" type="int" unsaved-value="null" />
   
    <property name="loginName" type="java.lang.String" column="loginName" unique="true" not-null="true" length="255"></property>
    <property name="loginPass" type="java.lang.String" column="loginPass" not-null="true" length="255"></property>
    <many-to-one name="parent" entity-name="CurrentUser" column="parent"></many-to-one>
    <list name="acls" table="acls" lazy="false">
      <key column="userid"/>
      <list-index column="sort"/>
      <composite-element class="Acl">
        <property name="path" type="string" length="255" not-null="true" />
        <property name="rights" type="integer" not-null="true" />
      </composite-element>
    </list>
    <property column="modified" name="modified" type="timestamp" not-null="true"/>
    <many-to-one name="owner" class="User" entity-name="CurrentUser" column="ownerid"></many-to-one>

  </class>
 
  <class name="User" table="usersHistory" entity-name="HistoricalUser" >
    <id unsaved-value="null" name="historyId" column="id" type="java.lang.Long" access="property">
      <generator class="native"></generator>
    </id>
    <property name="effectiveStartDate" type="timestamp" column="startDate" />
    <property name="effectiveEndDate" type="timestamp" column="endDate" />
    <property name="modified" type="timestamp" column="endDate" update="false" insert="false" />
    <property name="version" type="integer" column="version" not-null="true" />
    <property name="id" type="long" column="masterId" not-null="true"/>
    <property name="active" type="boolean" column="active" not-null="true" />
    <many-to-one name="owner" column="ownerId" class="User" entity-name="CurrentUser"></many-to-one>
    <many-to-one name="modifiedBy" class="User" entity-name="CurrentUser" column="modifiedby"></many-to-one>
   
    <property name="loginName" type="java.lang.String" column="loginName" not-null="true" length="255"></property>
    <property name="loginPass" type="java.lang.String" column="loginPass" not-null="true" length="255"></property>
    <list name="acls" table="aclsHistory" lazy="false" >
      <key column="historyid"/>
      <list-index column="sort"/>
      <composite-element class="Acl" >
        <property name="path" type="string" length="255" not-null="true" />
        <property name="rights" type="integer" not-null="true" />
      </composite-element>
    </list>
  </class>
  <query name="updateHistoricalUser">UPDATE HistoricalUser SET endDate = :now WHERE masterId = :targetId AND endDate IS NULL</query>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

Code:
// already saved ? sohObject is user
            boolean updateHist = (sohObject.getId() != null);
            // save user
            Date now = new Date();
            sohObject.setModified(now);
            sohObject.setEffectiveStartDate(now);
            sohObject.setHistoryId(null);
            session.saveOrUpdate(getCurrentEntityName(),sohObject);
            session.flush();
            if (updateHist) {
               Query q = session.getNamedQuery("update" + getHistoricalEntityName());
               q.setTimestamp("now", now);
               q.setLong("targetId", sohObject.getId().longValue());
                q.executeUpdate();
             }
            
            session.flush();
            // System.out.println(session.getStatistics().getEntityKeys());
            session.evict(sohObject);
            // new history entry
            session.merge(getHistoricalEntityName(), sohObject);


Full stack trace of any exception that occurs:

Name and version of the database you are using:
MySQL 4.1.21

The generated SQL (show_sql=true):
see below

Debug level Hibernate log excerpt:
Code:
2006-10-23 16:28:37,640 DEBUG [org.hibernate.SQL] insert into usersHistory (startDate, endDate, version, masterId, active, ownerId, primaryGroupId, secondaryGroupId, modifiedby, loginName, loginPass, parentid) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2006-10-23 16:28:37,640 DEBUG [org.hibernate.jdbc.AbstractBatcher] preparing statement
2006-10-23 16:28:37,640 DEBUG [org.hibernate.persister.entity.AbstractEntityPersister] Dehydrating entity: [HistoricalUser#<null>]
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.TimestampType] binding '2006-10-23 16:28:37' to parameter: 1
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.TimestampType] binding null to parameter: 2
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.IntegerType] binding '1' to parameter: 3
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.LongType] binding '5' to parameter: 4
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.BooleanType] binding 'true' to parameter: 5
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.LongType] binding null to parameter: 6
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.LongType] binding null to parameter: 7
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.LongType] binding null to parameter: 8
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.LongType] binding null to parameter: 9
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.StringType] binding 'testuserServ1161613717593' to parameter: 10
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.StringType] binding 'pass' to parameter: 11
2006-10-23 16:28:37,640 DEBUG [org.hibernate.type.LongType] binding null to parameter: 12
2006-10-23 16:28:37,656 DEBUG [org.hibernate.id.IdentifierGeneratorFactory] Natively generated identity: 6
2006-10-23 16:28:37,656 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2006-10-23 16:28:37,656 DEBUG [org.hibernate.jdbc.AbstractBatcher] closing statement
2006-10-23 16:28:37,656 DEBUG [org.hibernate.transaction.JDBCTransaction] commit
2006-10-23 16:28:37,656 DEBUG [org.hibernate.impl.SessionImpl] automatically flushing session
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] flushing session
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] processing flush-time cascades
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] dirty checking collections
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushing entities and processing referenced collections
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.WrapVisitor] Wrapped collection in role: HistoricalUser.acls
2006-10-23 16:28:37,656 DEBUG [org.hibernate.persister.entity.AbstractEntityPersister] HistoricalUser.owner is dirty
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.DefaultFlushEntityEventListener] Updating entity: [HistoricalUser#6]
2006-10-23 16:28:37,656 DEBUG [org.hibernate.engine.Collections] Collection found: [HistoricalUser.acls#6], was: [<unreferenced>] (initialized)
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Processing unreferenced collections
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Scheduling collection removes/(re)creates/updates
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 insertions, 1 updates, 0 deletions to 1 objects
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 1 (re)creations, 0 updates, 0 removals to 1 collections
2006-10-23 16:28:37,656 DEBUG [org.hibernate.pretty.Printer] listing entities:
2006-10-23 16:28:37,656 DEBUG [org.hibernate.pretty.Printer] User
2006-10-23 16:28:37,656 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] executing flush
2006-10-23 16:28:37,656 DEBUG [org.hibernate.jdbc.ConnectionManager] registering flush begin
2006-10-23 16:28:37,656 DEBUG [org.hibernate.persister.entity.AbstractEntityPersister] Updating entity: [HistoricalUser#6]
2006-10-23 16:28:37,656 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2006-10-23 16:28:37,656 DEBUG [org.hibernate.SQL] update usersHistory set startDate=?, endDate=?, version=?, masterId=?, active=?, ownerId=?, primaryGroupId=?, secondaryGroupId=?, modifiedby=?, loginName=?, loginPass=?, parentid=? where id=?
2006-10-23 16:28:37,656 DEBUG [org.hibernate.jdbc.AbstractBatcher] preparing statement
2006-10-23 16:28:37,656 DEBUG [org.hibernate.persister.entity.AbstractEntityPersister] Dehydrating entity: [HistoricalUser#6]
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.TimestampType] binding '2006-10-23 16:28:37' to parameter: 1
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.TimestampType] binding null to parameter: 2
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.IntegerType] binding '1' to parameter: 3
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.LongType] binding '5' to parameter: 4
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.BooleanType] binding 'true' to parameter: 5
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.LongType] binding '6' to parameter: 6
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.LongType] binding null to parameter: 7
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.LongType] binding null to parameter: 8
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.LongType] binding null to parameter: 9
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.StringType] binding 'testuserServ1161613717593' to parameter: 10
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.StringType] binding 'pass' to parameter: 11
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.LongType] binding null to parameter: 12
------- this seems to be wrong ----
2006-10-23 16:28:37,656 DEBUG [org.hibernate.type.LongType] binding '6' to parameter: 13
2006-10-23 16:28:37,656 DEBUG [org.hibernate.jdbc.AbstractBatcher] Executing batch size: 1
2006-10-23 16:28:37,671 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2006-10-23 16:28:37,671 DEBUG [org.hibernate.jdbc.AbstractBatcher] closing statement
2006-10-23 16:28:37,671 DEBUG [org.hibernate.util.JDBCExceptionReporter] Could not execute JDBC batch update [update usersHistory set startDate=?, endDate=?, version=?, masterId=?, active=?, ownerId=?, primaryGroupId=?, secondaryGroupId=?, modifiedby=?, loginName=?, loginPass=?, parentid=? where id=?]
java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails
   at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:647)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:500)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:473)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:267)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
   at $Proxy3.saveUser(Unknown Source)
   at UserTest.testUserService(UserTest.java:129)
   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 junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
2006-10-23 16:28:37,671 WARN  [org.hibernate.util.JDBCExceptionReporter] SQL Error: 1216, SQLState: 23000
2006-10-23 16:28:37,671 ERROR [org.hibernate.util.JDBCExceptionReporter] Cannot add or update a child row: a foreign key constraint fails
2006-10-23 16:28:37,671 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:500)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:473)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:267)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
   at $Proxy3.saveUser(Unknown Source)
   at UserTest.testUserService(UserTest.java:129)
   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 junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails
   at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:647)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
   ... 34 more



Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.