JPA Criteria API

Run
How to run the sample
The source code for this sample can be found in the javaee7-samples GitHub repository. The first thing we need to do is to get the source by downloading the repository and then go into the samples folder:
git clone git://github.com/javaee-samples/javaee7-samples.git
cd javaee7-samples/jpa/criteria/
Now we are ready to start testing. You can run all the tests in this sample by executing:
mvn test
Or you can run individual tests by executing one of the following:
mvn test -Dtest=JpaCriteriaTest

Using the Criteria API to create queries

JpaCriteriaTest

In this sample we’re going to query a simple JPA Entity, using the JPA Criteria API and perform a select, update and delete operations.

The following JPA Entity, represents a Movie which has a name and a comma separated list of actors:

@Entity()
@Table(name = "MOVIE_CRITERIA")
@XmlRootElement()
@NamedQueries({@NamedQuery(name = "Movie.findAll", query = "SELECT m FROM Movie m"), @NamedQuery(name = "Movie.findById", query = "SELECT m FROM Movie m WHERE m.id = :id"), @NamedQuery(name = "Movie.findByName", query = "SELECT m FROM Movie m WHERE m.name = :name"), @NamedQuery(name = "Movie.findByActors", query = "SELECT m FROM Movie m WHERE m.actors = :actors")})
public class Movie implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id()
    @NotNull()
    private Integer id;
    @NotNull()
    @Size(min = 1, max = 50)
    private String name;
    @NotNull()
    @Size(min = 1, max = 200)
    private String actors;

    public Movie();

    public Movie(Integer id);

    public Movie(Integer id, String name, String actors);

    public Integer getId();

    public void setId(Integer id);

    public String getName();

    public void setName(String name);

    public String getActors();

    public void setActors(String actors);

    @Override()
    public boolean equals(Object o);

    @Override()
    public int hashCode();

    @Override()
    public String toString();
}

The select, update and delete operations are exposed using a simple stateless ejb.

Select every movie:

public List<Movie> listMovies() {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Movie> listCriteria = builder.createQuery(Movie.class);
    Root<Movie> listRoot = listCriteria.from(Movie.class);
    listCriteria.select(listRoot);
    TypedQuery<Movie> query = em.createQuery(listCriteria);
    return query.getResultList();
}

Update all the name of the movies to "INCEPTION" where the name of the movie is "Inception":

public void updateMovie() {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaUpdate<Movie> updateCriteria = builder.createCriteriaUpdate(Movie.class);
    Root<Movie> updateRoot = updateCriteria.from(Movie.class);
    updateCriteria.where(builder.equal(updateRoot.get(Movie_.name), "Inception"));
    updateCriteria.set(updateRoot.get(Movie_.name), "INCEPTION");
    Query q = em.createQuery(updateCriteria);
    q.executeUpdate();
    em.flush();
}

Delete all movies where the name of the movie is "Matrix":

public void deleteMovie() {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaDelete<Movie> deleteCriteria = builder.createCriteriaDelete(Movie.class);
    Root<Movie> updateRoot = deleteCriteria.from(Movie.class);
    deleteCriteria.where(builder.equal(updateRoot.get(Movie_.name), "The Matrix"));
    Query q = em.createQuery(deleteCriteria);
    q.executeUpdate();
    em.flush();
}

We’re just going to deploy the application as a web archive. Note the inclusion of the following files:

/META-INF/persistence.xml
/META-INF/create.sql
/META-INF/drop.sql
/META-INF/load.sql

The persistence.xml file is needed of course for the persistence unit definition. A datasource is not needed, since we can now use the new default datasource available in JEE7. We’re also using the new javax.persistence.schema-generation.* propertires to create, populate and drop the database.

@Deployment
public static WebArchive createDeployment() {
    WebArchive war = ShrinkWrap.create(WebArchive.class)
                               .addPackage("org.javaee7.jpa.criteria")
                               .addAsResource("META-INF/persistence.xml")
                               .addAsResource("META-INF/create.sql")
                               .addAsResource("META-INF/drop.sql")
                               .addAsResource("META-INF/load.sql");
    System.out.println(war.toString(true));
    return war;
}

In the test, we’re just going to invoke the different operations in sequence keeping in mind that each invocation might be dependent of the previous invoked operation.

@Test
public void testCriteria() {
    List<Movie> movies = movieBean.listMovies();        (1)
    assertEquals(4, movies.size());                     (2)
    assertTrue(movies.contains(new Movie(1)));
    assertTrue(movies.contains(new Movie(2)));
    assertTrue(movies.contains(new Movie(3)));
    assertTrue(movies.contains(new Movie(4)));

    movieBean.updateMovie();                            (3)
    movies = movieBean.listMovies();
    assertEquals(4, movies.size());                     (4)
    assertEquals("INCEPTION", movies.get(2).getName()); (5)

    movieBean.deleteMovie();                            (6)
    movies = movieBean.listMovies();
    assertFalse(movies.isEmpty());
    assertEquals(3, movies.size());                     (7)
    assertFalse(movies.contains(new Movie(1)));         (8)
}
  1. Get a list of all the movies in the database.

  2. 4 movies loaded on the db, so the size shoud be 4.

  3. Update name to "INCEPTION" where name is "Inception"

  4. Size of movies should still be 4.

  5. Verify the movie name change.

  6. Now delete the movie "Matrix"

  7. Size of movies should be 3 now.

  8. Check if the movie "Matrix" is not on the list.

Share the Knowledge

Find this sample useful? Share on

There's a lot more about JavaEE to cover. If you're ready to learn more, check out the other available samples.

Help Improve

Find a bug in the sample? Something missing? You can fix it by editing the source, making the correction and sending a pull request. Or report the problem to the issue tracker

Recent Changelog

  • Jul 15, 2014: Removed header license. the licensing is now referenced in the license file in the root of the project by Roberto Cortez
  • Jan 13, 2014: Added javadoc for jpa criteria project by Roberto Cortez
  • Jan 11, 2014: Added test for jpa criteria project by Roberto Cortez
  • Sep 17, 2013: Removing netbeans configuration file by Arun Gupta
  • Aug 29, 2013: Better output messages by Arun Gupta
  • Aug 27, 2013: Moving the source code from http://svn.java.net/svn/glassfish~svn/branches/arun/javaee7-samples/samples/ by Arun Gupta
How to help improve this sample
The source code for this sample can be found in the javaee7-samples GitHub repository. The first thing you need to do is to get the source by downloading the repository and then go into the samples folder:
git clone git://github.com/javaee-samples/javaee7-samples.git
cd javaee7-samples/jpa/criteria/

Do the changes as you see fit and send a pull request!

Good Luck!