简体   繁体   English

@OrderBy被忽略

[英]@OrderBy is ignored

I am trying to retrieve a ordered list of Elements from a OneToMany relation but it seems that @OrderBy is simply ignored?! 我正在尝试从OneToMany关系中检索元素的有序列表,但似乎@OrderBy只是被忽略了?! The application uses eclipselink 2.1. 该应用程序使用eclipselink 2.1。 The test data base is derby embedded. 测试数据库是derby嵌入式的。

Here are the relevant (imho) parts of the code: 以下是代码的相关(恕我直言)部分:

@Entity
public class VotingEntity implements Voting {

    ...

    /**
     * A voting has at least one question.
     */
    @OneToMany(mappedBy = "voting", targetEntity = QuestionEntity.class, cascade = { CascadeType.PERSIST,
            CascadeType.REMOVE, CascadeType.REFRESH })
    @OrderBy("groupNumber")
    private List<QuestionEntity> questions = new ArrayList<>();

    ...

}

QuestionEntity: QuestionEntity:

@Entity
public class QuestionEntity implements Question {
    ... 
    /**
     * Could be used to group questions e.g. by pages.
     */
    private Integer groupNumber;
    ...
}

With this code i create a test entity: 使用此代码,我创建了一个测试实体:

public class VotingInstance {

    private VotingEntity voting;

    public VotingInstance() {
        voting = new VotingEntity();
        //other setters
        ...     
        voting.setQuestions(createQuestions(voting));
    }

    public VotingEntity getVoting(){
        return voting;
    }

    /**
     * 
     * @return a list with test questions.
     */
    private List<QuestionEntity> createQuestions(VotingEntity voting) {
        List<QuestionEntity> result = new ArrayList<>();
        //question 1
        QuestionEntity q1 = new QuestionEntity();
        q1.setVoting(voting);
        q1.setGroupNumber(3);
        ...
        result.add(q1);
        //question 2
        QuestionEntity q2 = new QuestionEntity();
        q2.setGroupNumber(1);;
        q2.setVoting(voting);
        ...
        result.add(q2);
                //question 3
        QuestionEntity q3 = new QuestionEntity();
        q3.setVoting(voting);
        q3.setGroupNumber(2);
        ...
        result.add(q3);
        return result;

    }

    ...

}

And here is the actual test: 这是实际的测试:

public class PersistenceTest {

    @Rule
    public TemporaryFolder temp = new TemporaryFolder();

    EntityManager em;

    VotingEntity voting;

    @Before
    public void init() {
        voting = new VotingInstance().getVoting();
        em = new TestDbConfig(temp.getRoot().toString()).createEm();
        em.getTransaction().begin();
        em.persist(voting);
        em.getTransaction().commit();
        em.clear();
    }

    @After
    public void close() {
        em.close();
    }

    @Test
    public void checkVoting() {
        VotingEntity v = em.find(VotingEntity.class, voting.getID());
        for (Question q : v.getQuestions()) {
            System.out.println("q-id: " + q.getID() + " group: " + q.getGroupNumber());
        }
    }
}

The output is sorted by id (default without OrderBY) but q2 should be first (orderNumer=1 ) and q1 should be second?! 输出按ID排序(默认不带OrderBY),但q2应该是第一个(orderNumer = 1),而q1应该是第二个?! So what to do to get an ordered list (i don't need to keep the order ind db, only the output is relevant). 因此,如何获得有序列表(我不需要将订单保持在ind db中,只有输出才是相关的)。

UPDATE: Some comments suggest to add a third question and create output to check actual groupnumber. 更新:一些评论建议添加第三个问题并创建输出以检查实际的组号。 i tried this and all is fine. 我尝试了这个,一切都很好。 I updated the code above. 我更新了上面的代码。 The output is: 输出为:

q-id: 2 group: 3
q-id: 6 group: 1
q-id: 8 group: 2

As per http://docs.oracle.com/javaee/5/api/javax/persistence/OrderBy.html , OrderBy only orders the QuestionEntity instances at the point the association is retrieved. 根据http://docs.oracle.com/javaee/5/api/javax/persistence/OrderBy.html,OrderBy仅在检索关联点时对QuestionEntity实例进行排序。 The missing peice is that you seem to be creating the VotingEntity and are likely recreating the questions list at the same time - JPA will only set the order when it is returned from the database. 缺少的一点是,您似乎正在创建VotingEntity,并且可能同时在重新创建问题列表-JPA仅在从数据库返回时设置顺序。 It is up to the application to maintain it. 由应用程序来维护它。

Try calling em.refresh(v) to see what I mean. 尝试调用em.refresh(v)来了解我的意思。 This should cause the the collection to be refreshed from the database. 这将导致从数据库刷新集合。

The problem you are encountering is that JPA allows for a second level cache. 您遇到的问题是JPA允许二级缓存。 So when you create the VotingEntity with the unordered list, it sticks around unordered in the cache and isn't fetched from the database. 因此,当您使用无序列表创建VotingEntity时,它会在缓存中无序排列,并且不会从数据库中获取。 To guarantee ordering, the application will need to maintain it at all times, or refresh it (and/or clear the cache) when order needs to be reasserted. 为了保证订购,应用程序将需要始终维护它,或者在需要重新确认订购时刷新它(和/或清除缓存)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM