views:

1563

answers:

5

so I have a persistent entity that has a @OneToMany list of another entity and I need the list order to be able to be edited by the user, which works wonderfully, I can completely re-order the java List in memory and when I save() the object, the order of links in the linking table DOES change... however, it changes to the reverse order of what the user set. However, if you pull the entity back up before closing the program, it shows up correct, because it's not reloading, and if you reload the program, again, it's backwards.

Is this just not something I'm supposed to do, depend on that order? But making another order column seems redundant since there IS an order anyway, and I can seem to change it... I just need it to save not backwards...

Any ideas? Joshua

A: 

Have you implemented compareTo on that object hierarchy?

Pietro Polsinelli
A: 

Is your Hibernate layer using Sets? I believe it does by default. The set interface (and its concrete implementations) do not maintain insertion order.

Alternatively, you may want to look at your queries, are you using an "order by"?

I'd also trying looking at the collection in memory by using a debugger. Your view code could be re-ordering the Collection. At the very least the debugger will be useful to see at what exact point your collection is being reverse.

James McMahon
+1  A: 

I think there is no way to achieve this direct with lists. We at work use the following:

If you want to give your user full control over the order of entities, you should add a new field for example:

@Entity
public class Todo {
  @Id private Long id;
  private int position; 
  // + public setter/getter 
} 

@Entity
public class Todos {
  @Id private id;

  @OneToMany
  private List<Todo> todos = new LinkedList<Todo>();
  // + public setter/getter     
}

and then put a order by position in all queries or implement a Comparator for Todos and use Collections.sort( List lst, Comparator cmp ) to sort your list in memory.

public class TodoComparator implements Comparator {
  public int compare(Object o1, Object o2) {
    Todo t1 = (Todo)o1;
    Todo t2 = (Todo)o2;
    return t2.getPosition() - t1.getPosition();
  }
}

Collection.sort(todos,new TodosComparator());

after your user is finished to reorder the list, (before save) renumber the list:

for(int pos=0; pos < todos.size(); pos++ )
 todos.get(pos).setPosition(pos);

and save todos. And enjoy the full control.

KlausMeier
Hi Joshua, if my answer helped can you please vote for i or mark it with green checkmark? (To give a good answer is really a lot of work)
KlausMeier
Good answer. But you should format your code.
Johannes Brodwall
Thxs, I formated the code.
KlausMeier
A: 

Are you operating directly on the list?

object.getItems().add/remove/set ...

Try instead making a copy

List items = new ArrayList(object.getItems());

then operating on that, then setting the full collection in one shot:

object.setItems(items)
z5h
+1  A: 

Hibernate has support of ordered elements using IndexColumn annotation.

Here is an example from "Java Persistence with Hibernate" book :

@org.hibernate.annotations.CollectionOfElements
@JoinTable(
name = "ITEM_IMAGE",
joinColumns = @JoinColumn(name = "ITEM_ID")
)
@org.hibernate.annotations.IndexColumn(
name="POSITION", base = 1
)
@Column(name = "FILENAME")
private List<String> images = new ArrayList<String>();
Pavel Rodionov