Hibernate version:3.2.0.ga
Code between sessionFactory.openSession() and session.close():
see below...
Name and version of the database you are using:
MySQL 4.1.13
The question may be related to this but I'm not sure.
Problems with Session and transaction handling?
Read this: http://hibernate.org/42.html I'm using Hibernate in tomcat with the JDBC transaction handling as described in the document above...
Question: Is it possible to have multple "updates" where each update uses the initial data values in a table?
I'm trying to implement a tree as a "nested set" and I'm trying to implement a move node function.
The data set might look like this:
Code:
A 2 [127,150] (11 children)
. B(2,0) [128,129] (0 children)
. B(2,1) [130,131] (0 children)
. B(2,2) [132,133] (0 children)
. B(2,3) [134,135] (0 children)
. B(2,4) [136,137] (0 children)
. A 3 [138,149] (5 children)
. . B(3,0) [139,140] (0 children)
. . B(3,1) [141,142] (0 children)
. . B(3,2) [143,144] (0 children)
. . B(3,3) [145,146] (0 children)
. . B(3,4) [147,148] (0 children)
Where the numbers in brackets represent the left and right extents of the tree nodes.
I want to move node "A 3" before node B(2,0) so I have three updates in the method like this...
Code:
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
StringBuilder moveLeftUpdate = new StringBuilder();
moveLeftUpdate.append("update ")
.append(name)
.append(" set right_extent = right_extent - :offset, left_extent = left_extent - :offset ")
.append(" where left_extent >= :thisLeft and right_extent <= :thisRight");
int moveLeftResult = session.createQuery( moveLeftUpdate.toString())
.setInteger("offset", offset)
.setInteger("thisLeft", left)
.setInteger("thisRight", right)
.executeUpdate();
LOG.info("MOVE LEFT RESULTS :: "+ moveLeftResult);
StringBuilder moveRightUpdate = new StringBuilder();
moveRightUpdate.append("update ")
.append(name)
.append(" set right_extent = right_extent + :offset, left_extent = left_extent + :offset ")
.append(" where left_extent >= :referenceLeft and right_extent <= :referenceRight");
int moveRightResult = session.createQuery( moveRightUpdate.toString())
.setInteger("offset", offset)
.setInteger("referenceLeft", referenceLeft)
.setInteger("referenceRight", referenceRight)
.executeUpdate();
LOG.info("MOVE RIGHT RESULTS :: "+ moveRightResult);
if(rangeDifference != 0 && (left - referenceRight > 1)) {
StringBuilder shiftInteriorUpdate = new StringBuilder();
shiftInteriorUpdate.append("update ")
.append(name)
.append(" set right_extent = right_extent + :range, left_extent = left_extent + :range ")
.append(" where left_extent > :referenceRight and right_extent < :thisLeft");
int interiorShiftResult = session.createQuery( shiftInteriorUpdate.toString())
.setInteger("range", rangeDifference)
.setInteger("referenceRight", referenceRight)
.setInteger("thisLeft", left)
.executeUpdate();
LOG.info("SHIFT INTERIOR RESULTS :: "+ interiorShiftResult);
}
tx.commit();
With this code in the example the log prints out:
Code:
MOVE LEFT RESULTS :: 6
MOVE RIGHT RESULTS :: 1
SHIFT INTERIOR RESULTS :: 7
In other words, the updated value from the first update are within the range of the last update and get updated twice.
I thought transactions where suppposed to prevent this, but either: A. I'm not using transactions correctly, B. don't have them set up correctly, or C. transactions are not the proper way of dealing with this.
Can anyone tell me which option I'm experiencing?