我有一个持久化实体,其中包含另一个实体的@OneToMany
列表,我需要能够由用户编辑的列表顺序,这非常有效。我可以在内存中完全重新排序java List,当我save()对象时,链接表中链接的顺序确实发生了变化。但是,它会更改为用户设置的相反顺序。但是,如果在关闭程序之前将实体拉回来,它会显示正确,因为它没有重新加载。如果你重新加载程序,它又会倒退。
这不是我应该做的事情,取决于那个顺序吗?但是制作另一个订单栏似乎是多余的,因为无论如何都有订单,我似乎可以改变它。我只是需要它来保存而不是倒退。
有什么想法吗?
答案 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)