Alexander Müller
Alexander Müller

Reputation: 547

OneToMany + JoinTable + OrderColumn: Order is written correctly but not read

I have an entity that can consist of itself:

class Group {
    // ...
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinTable(
        name = "group_group",
        joinColumns = @JoinColumn(name = "id"),
        inverseJoinColumns = @JoinColumn(name = "parentgroup_id")
    )
    @OrderColumn
    private List<Group> groups = new ArrayList<Group>();

    @ManyToOne
    private Group parentGroup;

    public List<Group> getGroups() {
        return groups;
    }

    public Group getGroup() {
        return parentGroup;
    }
}

I can create a group and add two child groups:

Group parent = new Group();
Group child1 = new Group();
Group child2 = new Group();

parent.getGroups().add(child1);
parent.getGroups().add(child2);

parent = groupRepository.save(parent);

// parent.getGroups().get(0).getId() == child1.getId()
// parent.getGroups().get(1).getId() == child2.getId()

But this seems to be a coincidence. I am able to update the order (e.g. using Collections.sort) and the join table rows are updated correctly.

It does not matter how I load the parent group, the child groups are always in the order of creation. The executed SQL query is:

SELECT t1.ID, t1.PARENTGROUP_ID FROM GROUP t0, GROUP t1 WHERE ((t1.PARENTGROUP_ID = ?) AND (t0.ID = t1.PARENTGROUP_ID))

There is no ORDER BY which seems wrong. How can I persuade EclipseLink to add it?

Upvotes: 1

Views: 1562

Answers (2)

Alexander M&#252;ller
Alexander M&#252;ller

Reputation: 547

The problem was that I tried to load the child group entities using a CrudRepository. The repository ignores the @OrderColumn annotation. I fixed it by fetching the parent group and using getGroups().

Upvotes: 1

Kevin Bowersox
Kevin Bowersox

Reputation: 94489

Try using the @OrderBy which does not rely on the database. You will need to provide a field from Group to order by (note field not column).

@OrderBy("fieldNameGoesHere DESC")
private List<Group> groups = new ArrayList<Group>();

OrderColumn will maintain the order of the list within the database, which carries additional performance and maintenance overhead. OrderBy puts the onus on the persistence provider to maintain the order of the entities, however the order will not persist across persistence contexts.

For more information, checkout this blog post I created regarding @OrderBy.

Upvotes: 0

Related Questions