我尝试在地图内按特定顺序存储“模块”数据。我使用TreeMap来实现这一点。 当我读取数据时,我得到的顺序错误。它以键值9开始并停止0. ??? JPA做了吗?否则然后将值“放”到TreeMap中?
@OneToMany(
mappedBy="prditem",
fetch=FetchType.LAZY,
cascade=CascadeType.ALL,
orphanRemoval=true,
targetEntity=PubModule.class
)
@JoinColumn(name="prditmID")
@MapKey(name="order")
private Map<Integer, PubModule> modules = new PubModulesMap();
public class PubModulesMap extends TreeMap<Integer,PubModule> {
@Override
public PubModule put(Integer key, PubModule value) {
PubModule old = (PubModule)this.get(key);
if (old!=null) {
old.setPrditem(value.getPrditem());
....
}
Iterator <PubModule> it = list.values().iterator();
while (it.hasNext()) {
PubModule pm = it.next();
System.out.println(pm.getOrder());
}
9 8 7 6 五 4 3 2 1 0
答案 0 :(得分:1)
出现意外订单的原因是,JPA不理解地图应该排序。
通用解决方案是为地图创建一个getter方法:
public Map<Integer, PubModule> getModules() {
if (modules == null) {
modules = new PubModulesMap();
} else if (!(modules instanceof TreeMap)) {
modules = new TreeMap(modules); // Or new PubModulesMap(modules)
}
return modules;
}
如果你正在使用hibernate,你应该添加@Sort(type = SortType.NATURAL)注释。
答案 1 :(得分:1)
JPA在从数据库读取时使用自己的Map实现来支持LAZY和更改跟踪。
对于EAGER关系,如果您愿意,可以使用自己的特定课程。只需将字段类型设置为此类,或使用DescriptorCustomizer在OneToManyMapping上配置ContainerPolicy。
您还可以为已排序的映射定义瞬态字段,并使用您自己的get / set方法从持久性映射中进行延迟初始化。
您还可以使用OrderBy对数据库进行排序。