views:

250

answers:

2

Hi,

I got an Java application using SQL tables that contains an ordered list of entities, ordered by an order column. I would like to add/remove things in/from the middle of the list. Now, I'm wondering if some persistence framework / orm / you-name-it could provide this kind of functionality with batch update of order column.

At the basic case Hibernate (and probably others also) provide this functionality. The problem is that the objects are handled one at time, which becomes problem when the list is large enough. Alternate solution would be to do the thing with a batch SQL update, like the following for example:

UPDATE table SET order_col = order_col + 1 WHERE order_col > 47
INSERT TO table VALUES ('new_id', 'new_description, ..., 47)

which is done quite fast by the database engine but isn't supported.

Now, I understand that this kind of batch updates don't fit so well when thinking the objects and their versioning, dirty checking etc. I'd still ask if somebody has some nice ideas or if some persistence framework / ORM / you-name-it would provide some help. Of course I can do the thing with custom SQL/HQL/... but was wondering if there would be some solution already (I'd think somebody else could have done something like this before and even put it under open source). Also other good ideas related to the problem are welcome =)

+2  A: 

My advice is to do two things:

  1. Choose very large increments between your items, say one million. This way you can move an item at 8,000,000 to before 7,000,000 by changing just it to 6,500,000; and
  2. Every now and again reorder the items as a batch job.

The large increments don't eliminate the problem of doing a large reorder but the need to do a big reorder highly unlikely and the batch job is there to reorder them say once every day/week/month as required.

Changing a whole bunch of items at once is just messy and asking for trouble.

cletus
+1: would do it exactly like this.
David Schmitt
+1  A: 

If you really want to end up with a continuous sequential order, you can do it like this:

First of all, multiply the sortorder by say 1000

UPDATE testtable SET sortorder = sortorder * 1000

Now do your inserts and insert suitable sortorder values to have the new entries in the right place.

Now do a table update and update the values using the ROW_NUMBER function

UPDATE testtable
SET sortorder = subq.newsortorder
FROM
  (
  SELECT
    ID as innerID,
    ROW_NUMBER() OVER(ORDER BY sortorder ASC) as newsortorder
  FROM testtable
  ) subq
WHERE subq.innerID = ID

The ID is selected as innerID as the updated table can't be aliased and the ID column would otherwise end up ambiguous.

This is updating the sortorder with the row's number when sorted by sortorder.

John
+1, added link and minor formatting
David Schmitt