I was trying to have a look at the MySQL query log in the different cases and saw the following:
With doWork/SQL/batch: 091216 12:55:38 5148 Query /* */ insert into User (id, version, description, name, superior_pid, userName) values ('d0c9688d-03ff-4f7a-83e9-1c009894e165', 0, 'asdf', 'asdf', null, 'user20') 5148 Query /* */ insert into UserGroups (User_pid, groups_pid) values (20, 50) 091216 12:55:40 5148 Query /* */ XA END 0x4800000052502e977065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c5033373030,0x7065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c50333730302c00,0x4a5453 5148 Query /* */ XA COMMIT 0x4800000052502e977065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c5033373030,0x7065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c50333730302c00,0x4a5453 ONE PHASE
With session.merge: 091216 12:59:34 5143 Query /* */ insert into User (id, version, description, name, superior_pid, userName) values ('b02a1eb9-572a-483f-983c-e39dddcbf016', 0, 'asdf', 'asdf', null, 'user21') 5145 Query /* */ SELECT @@session.tx_isolation 5145 Query /* */ insert into UserGroups (User_pid, groups_pid) values (21, 50) 091216 13:00:25 5143 Query /* */ XA END 0x5900000052502e977065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c5033373030,0x7065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c50333730302c00,0x4a5453 5143 Query /* */ XA ROLLBACK 0x5900000052502e977065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c5033373030,0x7065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c50333730302c00,0x4a5453
They are very simular, but I noticed the "SELECT @@session.tx_isolation" between "insert into User" and "insert into UserGroups" in the "session.merge" case. I was trying some different things, and ended up finding out the this will work: try {session.connection().getTransactionIsolation();} catch (Exception e) {} session.merge(user); Remember that "session.merge(user);" alone does NOT work.
For... try {session.connection().getTransactionIsolation();} catch (Exception e) {} session.merge(user); ...I get the following in MySQL query log: 091216 13:41:31 5156 Query /* */ SELECT @@session.tx_isolation 091216 13:41:32 5156 Query /* */ insert into User (id, version, description, name, superior_pid, userName) values ('2a733b3f-e42a-4322-a9be-84524e04dd7d', 0, 'asdf', 'asdf', null, 'usernext') 5156 Query /* */ insert into UserGroups (User_pid, groups_pid) values (30, 50) 5156 Query /* */ XA END 0xfa00000052502e977065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c5033373030,0x7065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c50333730302c00,0x4a5453 5156 Query /* */ XA COMMIT 0xfa00000052502e977065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c5033373030,0x7065722d7374656666656e73656e732d6d6163626f6f6b2d70726f2e6c6f63616c2c7365727665722c50333730302c00,0x4a5453 ONE PHASE
It seems like "try {session.connection().getTransactionIsolation();} catch (Exception e) {}" forces the "SELECT @@session.tx_isolation" up before "insert into User" and that it makes the problem not occur.
I interpret is as: Hibernate have a look at getTransactionIsolation() between "insert into User" and "insert into UserGroups" and that makes the thing fail. Why Hibernate does getTransactionIsolation() i dont know. Why MySQL fails on that scenario is a huge mystery for me! Any attempt to explain is very welcome!
|