one-to-one inverse concurrency issue
Concurrent requests operating on a one-to-one inverse relation can cause an inconsistent database, reproducible with the following example:
application test entity A { b -> B } entity B { a -> A (inverse=A.b) } var a1 := A{} define page root(){ init{ //will break db on concurrent access when a1.b was null, because there is no transaction conflict (only row in B is added), // but there is a logical conflict (multiple B's pointing to A) which breaks subsequent queries a1.b := B{}; } } define page root1(){ init{ a1.b := null; } } // start 2 apache benchmarks: // ab -n1000 -c10 http://localhost:8080/onetooneissue/ // ab -n1000 -c10 http://localhost:8080/onetooneissue/root1
This is related to the mapping strategy of the Hibernate @OneToOne annotation: since only one side contains the reference (table of B), concurrent changes to a.b were a.b was null will not be detected as a transaction conflict (B’s are different and A is not touched).
Adding a uniqueness constraint on the reference column can cause the one-to-one inverse to not function at all, depending on the order of the B row edits.
The best solution seems to be to automatically increase the version property of an entity when an inverse property is changed, which would cause a transaction conflict in this example, instead of inconsistent data.
Submitted by Danny Groenewegen on 7 July 2010 at 13:41
Issue Log
Looks like this is a known open bug in Hibernate (voted it): http://opensource.atlassian.com/projects/hibernate/browse/HHH-4289
I’ll just add the fix to the WebDSL compiler in the mean time.
fixed in rev 4047
also tried the many-to-many case, but there the version property seems to be updated on both sides preventing this issue
Log in to post comments