[hibernate-issues] [Hibernate-JIRA] Created: (HHH-3102) Cascading ManyToOne collections do not eagerly set identifiers on saveOrUpdate()

Paul Cowan (JIRA) noreply at atlassian.com
Tue Feb 12 00:47:33 EST 2008


Cascading ManyToOne collections do not eagerly set identifiers on saveOrUpdate()
--------------------------------------------------------------------------------

                 Key: HHH-3102
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3102
             Project: Hibernate3
          Issue Type: Bug
          Components: core
    Affects Versions: 3.2.4.sp1
            Reporter: Paul Cowan
            Priority: Minor
         Attachments: HibernateKeyPoolTest.java

Hi all,

Not 100% sure if you'd call this a 'bug' as I'm not sure if the correct behaviour is actually specified anywhere. It's certainly oddly inconsistent though.

Please find attached a standalone test case (requires HSQLDB on the classpath; amend setUp() if you need to use something else) which models a parent-child mapping between 'Mouth' (1) and 'Teeth' (many). The Mouth -> Teeth relationship is bidirectional, with CascadeType.ALL on the single-valued end. Both Mouth and Tooth use a @GenericGenerator, which simply allocates integers from a static keypool.

A mouth with one tooth is created, saveOrUpdate()d, session is flushed, a new tooth is added, mouth is saveOrUpdate()d again, and session is again flushed. The debug output is as follows:

*** After creation
Mouth (id=null) has teeth [canine(id=null)]
*** Save
Mouth (id=1) has teeth [canine(id=2)]
*** Flush
Hibernate: insert into Mouth (id) values (?)
Hibernate: insert into Tooth (mouthId, name, id) values (?, ?, ?)
Mouth (id=1) has teeth [canine(id=2)]
*** Add new
Mouth (id=1) has teeth [canine(id=2), molar(id=null)]
*** Save again
Mouth (id=1) has teeth [canine(id=2), molar(id=null)]
*** Flush again
Hibernate: insert into Tooth (mouthId, name, id) values (?, ?, ?)
Mouth (id=1) has teeth [canine(id=2), molar(id=3)]

As you can see, when initially created the IDs for the mouth and tooth are both null (obviously correct). The saveOrUpdate() on the Mouth object then generates identifier values, even though no DB write has been done yet (the .flush()). So far, so good.

However, when a NEW transient Tooth instance ("molar") is added to the Mouth, and saveOrUpdate() is called once more, the id generator is not invoked, UNTIL such time as the session is flushed. 

While I guess it's fine  for an object in the 'persistent' state not to actually have an identifier until flush-time (e.g. when using DB-side IDENTITY-type generation), it just seems inconsistent that with a @GenericGenerator the behaviour would vary depending on whether the PARENT object was already persistent or not.

There are some obvious workarounds (e.g. flush the session upon saving, or save the child entity first independently) but I thought I'd clarify if this behaviour is by design or not and suggest that this be made consistent.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list