Search code examples
javajpamany-to-manyeclipselink

JPA : How to save list with order in a many-to-many relationship


When I persist a list which has an order, the result in the database has a different order. How can I persist a many-to-many relationship with list order in JPA?

@Entity
@Table(name = "house")
public final class House {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Basic(optional = false)
    @Column(name = "name")
    private String name

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "house_room",
            joinColumns =
            @JoinColumn(name = "id_house", referencedColumnName = "id"),
            inverseJoinColumns =
            @JoinColumn(name = "id_room", referencedColumnName = "id"))
    private List<Room> rooms;
}

House object:

Room room1 = new Room();
room1.setName("Kitchen");

Room room2 = new Room();
room2.setName("Bathroom");

Room room3 = new Room();
room3.setName("Bedroom");

List<Run> runs = new ArrayList<Run>();
rooms.add(0,room2);
rooms.add(1,room1);
rooms.add(2,room3);

House cottage = new House();
cottage.setRooms(rooms);

persist(cottage); // order in database should be "room2", "room1" then "room3" but it is saved as "room1", "room2" then "room3"

Solution

  • There are 2 ways to order list in JPA using @OrderBy and @OrderColumn annotations. @OrderColumn is perhaps what you are looking for.

    @OrderBy

    Specify an ordering rule based on the comparison of a particular attribute of the entity or element

    Example:

    @OrderBy("name ASC")
    private List<Room> rooms;
    

    By adding an @OrderBy annotation on the mapping, we can indicate that we want the rooms to be ordered in ascending alphabetical order by its name attribute. Note: We needn’t have included the ASC in the @OrderBy annotations because it would be ascending by default.

    Simply changing the order of the items in a List in memory will not cause that order to be stored in the database at commit time.

    The annotation applies only when collection is retrieved from the database. That means, the order will not be stored in the database but when data is retrieved from the DB and stored to the List collection in memory, they will be ordered.

    @OrderColumn

    The OrderColumn annotation specifies a column that is used to maintain the persistent order of a list. Example:

    @OrderColumn(name="ROOM_ORDER")
    private List<Room> rooms;
    

    This means you have an additional column named "ROOM_ORDER" that will indicate the order of your items in your table.