hibernate OneToMany列表排序持续但反转?

时间:2009-05-21 20:59:06

标签: hibernate list

我有一个持久化实体,其中包含另一个实体的@OneToMany列表,我需要能够由用户编辑的列表顺序,这非常有效。我可以在内存中完全重新排序java List,当我save()对象时,链接表中链接的顺序确实发生了变化。但是,它会更改为用户设置的相反顺序。但是,如果在关闭程序之前将实体拉回来,它会显示正确,因为它没有重新加载。如果你重新加载程序,它又会倒退。

这不是我应该做的事情,取决于那个顺序吗?但是制作另一个订单栏似乎是多余的,因为无论如何都有订单,我似乎可以改变它。我只是需要它来保存而不是倒退。

有什么想法吗?

6 个答案:

答案 0 :(得分:4)

Hibernate使用IndexColumn批注支持有序元素。

以下是"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>();

答案 1 :(得分:2)

你的Hibernate图层是否使用了套装?我相信它确实是默认的。设置界面(及其具体实现)维护插入顺序。

或者,您可能想查看您的查询,是否使用“按订单”?

我还尝试使用调试器查看内存中的集合。您的视图代码可能正在重新订购Collection。至少调试器对于查看您的集合正在反向的确切位置非常有用。

答案 2 :(得分:2)

我认为没有办法直接用列表实现这一点。我们在工作中使用以下内容:

如果您想让您的用户完全控制实体的顺序,您应该添加一个新字段,例如:

@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     
}

然后在所有查询中按位置排序或实现Todos的Comparator并使用Collections.sort(List lst,Comparator cmp)对内存中的列表进行排序。

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());

用户完成重新排序列表后,(保存前)重新编号列表:

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

并保存待办事项。并享受完全控制。

答案 3 :(得分:2)

我遇到了同样的问题,我只是通过添加另一篇文章here中建议的 @OrderBy 注释来修复它。我认为它应该能够解决你的问题,这是我的代码:

   @Entity
    @Table(name = "my_library")
    public class MyLibrary implements java.io.Serializable{

    (...omitted)

    private List<Book> bookList = new ArrayList<Book>();   

    @OneToMany(mappedBy = "library", cascade = CascadeType.ALL)
    @OrderBy
    public List<Book> getBookList() {
        return bookList;
    }

    public void setBookList(List<Book> bookList) {
        this.bookList= bookList;
    }

    }

然后我能够将getListList()作为我在保存到DB时插入的相同顺序。 如果我们不指定列名称,如 @OrderBy(“xxxColumn”),则默认使用该实体的主键。在我的例子中,它使用Book的instanceId,它将始终遵循与插入顺序相同的顺序,因此它很好地满足了我的需求。

但是,我很好奇为什么订单首先是反向的。

答案 4 :(得分:0)

您是否在该对象层次结构上实现了compareTo?

答案 5 :(得分:0)

您是否直接在列表中操作?

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

尝试制作副本

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

然后对其进行操作,然后一次性设置完整的集合:

object.setItems(items)