2

我尝试在地图中以特定顺序存储“模块”数据。我使用 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 5 4 3 2 1 0

4

2 回答 2

1

JPA 在从数据库读取时使用自己的 Map 实现来支持 LAZY 和更改跟踪。

对于 EAGER 关系,您可以根据需要使用自己的特定类。只需将您的字段类型设置为此类,或使用 DescriptorCustomizer 在 OneToManyMapping 上配置 ContainerPolicy。

您还可以为排序映射定义一个瞬态字段,并使用您自己的 get/set 方法从持久性映射中进行延迟初始化。

您还可以使用 OrderBy 对数据库进行排序。

于 2012-11-20T14:44:01.993 回答
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;
}

如果您使用的是休眠,则应添加 @Sort(type = SortType.NATURAL) 注释。

于 2012-11-19T15:08:25.170 回答