Pages

Friday, July 19, 2013

Ordering collections in JPA tutorial

There's a possibility to order collections of entities by comparing their properties in JPA .
Let's look at how to do it.

Let's modify the application created in "JPA One-to-Many and Many-to-One mappings tutorial" post.

This post is available in Russian.

Create jpa_ordering_collections_tutorial database with artists and albums tables.
albums table has album_order column, which stores release order of every album starting with zero.
So, the first artist album's order is "0", second album's order is "1" and so on.
Add artist and its albums data:
CREATE DATABASE jpa_ordering_collections_tutorial;
USE jpa_ordering_collections_tutorial;

CREATE TABLE artists (
artist_id INT PRIMARY KEY,
artist_name VARCHAR(30)
);

CREATE TABLE albums (
album_id INT PRIMARY KEY,
album_name VARCHAR(50), 
album_order INT, 
artist_id INT, 
FOREIGN KEY (artist_id) REFERENCES artists (artist_id)
);

INSERT INTO artists VALUES (1, 'Franz Ferdinand');
INSERT INTO albums VALUES (1, 'Tonight: Franz Ferdinand', 2, 1);
INSERT INTO albums VALUES (2, 'You Could Have It So Much Better', 1, 1);
INSERT INTO albums VALUES (3, 'Franz Ferdinand', 0, 1);

Unlike the application described in "JPA One-to-Many and Many-to-One mappings tutorial" post, Album class doesn't have year property, but has order property instead:
package com.jpa.ordering.collections.tutorial.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "albums")
public class Album {

    @Id
    @Column(name = "album_id")
    private int id;

    @Column(name = "album_name")
    private String name;

    @Column(name = "album_order")
    private int order;

    @ManyToOne
    @JoinColumn(name = "artist_id")
    private Artist artist;

    public Album() {

    }

    public Album(int id, String name, int order) {
        this.id = id;
        this.name = name;
        this.order = order;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    public Artist getArtist() {
        return artist;
    }

    public void setArtist(Artist artist) {
        this.artist = artist;
    }

    @Override
    public String toString() {
        return "Album{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", order=" + order +
                '}';
    }
}

Ordering by entity identifier


Artist class is similar to the class described in "JPA One-to-Many and Many-to-One mappings tutorial" post.
To order collection of Album entities by id property add @OrderBy annotation to albums property:
package com.jpa.table.column.mappings.tutorial.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import java.util.List;

@Entity
@Table(name = "artists")
public class Artist {

    @Id
    @Column(name = "artist_id")
    private int id;

    @Column(name = "artist_name")
    private String name;

    @OneToMany(mappedBy = "artist")
    @OrderBy
    private List<Album> albums;

    public Artist() {

    }

    public Artist(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public List<Album> getAlbums() {
        return albums;
    }

    public void setAlbums(List<Album> albums) {
        this.albums = albums;
    }

    @Override
    public String toString() {
        return "Artist{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Add code that creates ArtistService object, finds an Artist entity and prints artist and its albums data to main() method of JpaOrderingCollectionsTutorial class:
package com.jpa.ordering.collections.tutorial;

import com.jpa.ordering.collections.tutorial.domain.Album;
import com.jpa.ordering.collections.tutorial.domain.Artist;
import com.jpa.ordering.collections.tutorial.service.ArtistService;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JpaOrderingCollectionsTutorial {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("JpaOrderingCollectionsTutorial");
        EntityManager em = emf.createEntityManager();
        ArtistService artistService = new ArtistService(em);

        System.out.println("--- Find artist and order its albums by id ---");
        Artist artist = artistService.findArtist(1);
        System.out.println(String.format("Found artist: %s", artist));
        for (Album album : artist.getAlbums()) {
            System.out.println(String.format("Artist album: %s", album));
        }
    }
}

Execute main() method:

Application has printed artist and its albums data ordered by identifier in ascending order.

Ordering by entity property


To order collection of Album entities by name property add @OrderBy annotation with property name and order.
To order in ascending order set order value to "ASC" or don't set it at all.
To order in descending order set order value to "DESC".
Let's order collection in ascending order:
@OrderBy("name ASC")
private List<Album> albums;

Execute main() method:

Application has printed artist and its albums data ordered by name property in ascending order.

Ordering by table column


albums table has album_order column, which stores release order of every album.
To order collection of Album entities by album_order column values add @OrderColumn annotation with column name to albums property:
@OrderColumn(name = "album_order")
private List<Album> albums;

Execute main() method:

Application has printed artist and its albums data ordered by album_order column values, which means we have successfully ordered collection of entities with @OrderBy and @OrderColumn annotations.


Folder structure:




Application source code is available at https://code.google.com/p/jpa-ordering-collections-tutorial/.

Recommended posts:

No comments:

Post a Comment