我试图从OneToMany关系中检索一个有序的Elements列表,但似乎只是忽略了@OrderBy?!该应用程序使用eclipselink 2.1。测试数据库是derby嵌入式。
以下是代码的相关(imho)部分:
@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:
@Entity
public class QuestionEntity implements Question {
...
/**
* Could be used to group questions e.g. by pages.
*/
private Integer groupNumber;
...
}
使用此代码我创建一个测试实体:
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;
}
...
}
这是实际测试:
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());
}
}
}
输出按id排序(默认情况下没有OrderBY),但q2应该是第一个(orderNumer = 1),q1应该是第二个?! 那么如何获得一个有序列表(我不需要保持命令ind db,只有输出是相关的。)
更新:有些评论建议添加第三个问题并创建输出以检查实际的组号。我试过这个,一切都很好。我更新了上面的代码。输出是:
q-id: 2 group: 3
q-id: 6 group: 1
q-id: 8 group: 2
答案 0 :(得分:1)
根据http://docs.oracle.com/javaee/5/api/javax/persistence/OrderBy.html,OrderBy仅在检索关联时对QuestionEntity实例进行排序。缺少的是你似乎在创建VotingEntity并且可能同时重新创建问题列表 - JPA只会在从数据库返回时设置顺序。由应用程序来维护它。
尝试调用em.refresh(v)来查看我的意思。这应该导致从数据库刷新集合。
您遇到的问题是JPA允许二级缓存。因此,当您使用无序列表创建VotingEntity时,它会在缓存中无序排列并且不会从数据库中获取。为了保证订购,应用程序将需要始终维护它,或者在需要重新声明订单时刷新它(和/或清除缓存)。