使用List的JPA一对多关系 - OrderBy忽略/不工作

时间:2014-06-20 13:23:38

标签: jpa eclipselink

我会尝试将问题更简单地表达出来:

@Entity
public class One implements Serializable {
...
@Id
@GeneratedValue
private Long id;
@OneToMany
@OrderBy("name ASC")
private List<Many> many;
...

首先,我使用一些多实体填充List并保留One-Entity。其次,我检索(em.find)One-Entity期望列表按许多#name的升序排列,但它没有按名称排序。列表按ID排序。如有必要,请填写完整的代码。

几天前的原帖:

我正在使用当前的Netbeans Glassfish软件包。

产品版本:NetBeans IDE 8.0(Build 201403101706) 更新:NetBeans IDE已更新为NetBeans 8.0 Patch 2版本 Java:1.7.0_51; Java HotSpot(TM)64位服务器VM 24.51-b03 运行时:Java(TM)SE运行时环境1.7.0_51-b13 系统:在x86_64上运行的Mac OS X版本10.9.3; UTF-8; de_DE(nb)

JPA @OrderBy注释完全被忽略。

@Entity
public class One implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Long id;
    @OneToMany
    @OrderBy("name ASC")
    private List<Many> many;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public List<Many> getMany() {
        return many;
    }

    public void setMany(List<Many> many) {
        this.many = many;
    }

}

许多实体

@Entity
public class Many implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    public Many() {
    }

    public Many(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

服务类(EJB)

@Stateless
public class Service {

    @PersistenceContext(unitName = "cwPU")
    private EntityManager em;


    public One createOne() {
        return em.merge(new One());
    }

    public Many createMany(String name) {
        return em.merge(new Many(name));
    }

    public One add(Long oneId, Long manyId) {
        One one = em.find(One.class, oneId);
        Many many = em.find(Many.class, manyId);
        one.getMany().add(many);
        return one;
    }

    public One find(Long id) {
        One one = em.find(One.class, id);
        return one;
    }

}

主要课程

public class Main {

    public static void main(String[] args) throws NamingException {
        EJBContainer container = EJBContainer.createEJBContainer();
        Context ctx = container.getContext();
        Service service = (Service) ctx.lookup("java:global/classes/Service");
        One one = service.createOne();
        Many many = service.createMany("the-first");
        service.add(one.getId(), many.getId());
        many = service.createMany("a-second");
        one = service.add(one.getId(), many.getId());
        one = service.find(one.getId());
        System.out.println("-------------------------------------------------");
        for (Many m : one.getMany()) {
            System.out.println(m.getName());
        }
        container.close();
    }

}

输出:

the-first
a-second

无论我写给@OrderBy注释(名称ASC,名称DESC,id ASC,id DESC),输出始终是id的升序。

知道我错过了什么吗?

2 个答案:

答案 0 :(得分:3)

@Orderby注释实际上并没有这样做。根据{{​​3}},注释&#34;指定集合元素的排序...在集合检索时。&#34;

因此注释会影响查询(查找)的结果,但不会决定将结果集存储到的集合中的顺序。

答案 1 :(得分:1)

解决方案是按照Chris和WPrecht的说法调用em.refresh(在正确的位置)。我必须在一个单独的EJB方法中执行此操作。

这确实工作:

public One find(Long id) {
    em.refresh(em.find(One.class, id)); // did not work
    One one = em.find(One.class, id);
    return one;
}

添加单独的刷新方法

public void refresh(Long id) {
    em.refresh(em.find(One.class, id));
}

并在主程序中调用它

...
service.refresh(one.getId());
one = service.find(one.getId());
...

作品!

可能我需要做更多阅读才能理解缓存。