2 Replies Latest reply on Jan 30, 2008 11:08 AM by Roland Burgermann

    Problem on updating M:N relations

    Roland Burgermann Newbie

      Hello all.

      I got a problem with updating the relation table between two entities.

      This problem only occurs when i'm using a "Listener" class to set a field from a MappedSuperclass. For a better understanding i have made a screenshot of my situation.

      [url=http://img221.imageshack.us/img221/7346/mtonrelationproblemjw1.jpg][img]http://img221.imageshack.us/img221/7346/mtonrelationproblemjw1.jpg[/img][/url]

      As you can see i have a GeneralEntity as MappedSuperclass with one attribute and two entities which inherit this field from the GeneralEntity. Additional the Parent and Child have one idFeld which is tagged as Identifier and one dataField from type String. Between Parent and child we have a M:N relation.

      When i send an update to the database with a parent object including a child object, the persist method is called and data is saved correctly in the database.

      When i send an update again (with or without changes) and using the same identifiers, then is no update on parent table, no update on child table, which is correct when nothing is changed, BUT we have an delete on the relation table!!

      I check the server log and found the following part, where the delete statement is triggered:

      2007-12-13 16:47:23,515 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] processing flush-time cascades
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] dirty checking collections
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.engine.CollectionEntry] Collection dirty: [com.trinitec.samples.ejb3xfire.Parent.child#PARENT01]
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.engine.Collections] Collection found: [com.trinitec.samples.ejb3xfire.Parent.child#PARENT01], was: [com.trinitec.samples.ejb3xfire.Parent.child#PARENT01] (initialized)
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 insertions, 2 updates, 0 deletions to 3 objects
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 (re)creations, 1 updates, 0 removals to 1 collections
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.pretty.Printer] listing entities:
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.pretty.Printer] com.trinitec.samples.ejb3xfire.Child{dataFeld2=Child_01, idFeld2=CHILD01, systemId=3}
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.pretty.Printer] com.trinitec.samples.ejb3xfire.Parent{child=[com.trinitec.samples.ejb3xfire.Child#CHILD01], dataFeld1=Parent_01, systemId=3, idFeld1=PARENT01}
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.pretty.Printer] com.trinitec.samples.ejb3xfire.Transaction{status=OK, startTime=1197560843453, pk=component[transactionId,principalId]{transactionId=2, principalId=rb}, endTime=0}
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.persister.collection.AbstractCollectionPersister] Deleting rows of collection: [com.trinitec.samples.ejb3xfire.Parent.child#PARENT01]
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
      2007-12-13 16:47:23,515 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.SQL] delete from PARENTS2CHILD where PARENTS_ID_FELD1_FK=? and CHILD_ID_FELD2_FK=?
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.persister.collection.AbstractCollectionPersister] done deleting collection rows: 1 deleted
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.persister.collection.AbstractCollectionPersister] Inserting rows of collection: [com.trinitec.samples.ejb3xfire.Parent.child#PARENT01]
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.persister.collection.AbstractCollectionPersister] done inserting rows: 0 inserted
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.jdbc.AbstractBatcher] Executing batch size: 1
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.jdbc.ConnectionManager] skipping aggressive-release due to flush cycle
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] processing flush-time cascades
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] dirty checking collections
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.engine.Collections] Collection found: [com.trinitec.samples.ejb3xfire.Parent.child#PARENT01], was: [com.trinitec.samples.ejb3xfire.Parent.child#PARENT01] (initialized)
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 insertions, 1 updates, 0 deletions to 3 objects
      2007-12-13 16:47:23,546 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 1 collections
      


      For a second test i add the annotation @persistence.column.update to the systemId attribute in the MappedSuperclass. So the system should ignore this field when updating.

      When i call the update method the first time. All data is inserted correctly to the database.

      When i call the update method the second time to change the dataFields i got an unique constraint error from the database, because the system is trying to make a insert on the relation table!! This is not possible because the necessary entry is existing yet.

      The server log looks similar to the server log above, but instead of the delete statement we have an insert statement.

      It's a bit of a strange problem, because this only happens when using a listener and setting a field from a MappedSuperclass in there and having a M:N relation or a relation which produces a relation table in the database.

      Do i something wrong or is this maybe a bug?
      Can someone give me a hint?

      Thanks for reading my problem.
      Roland (Darquerus)

      PS: Following workaround exists: Move the field from the MappedSuperclass to the entities. After this change i can set the field through the listener and everything is okay, also when sending several updates. But i won't move all my fields from the MappedSuperclass into my ~150 entities in my big application. :)