Data Persistence with Jakarta Data

duration 15 minutes

Prerequisites:

What you’ll learn

You will learn how to use Jakarta Data to store data as well as the simple, yet powerful options it provides for querying data. This will include writing queries that are created from the method name, as well as queries using annotations. Finally, you will learn about the Jakarta Data Query Language (JDQL).

The application demonstrates a number of different queries that are possible with Jakarta Data. As you proceed through the guide, you will be able to write your own queries with the provided sample data.

What is Jakarta Data?

Jakarta Data is a new data access specification being released with Jakarta EE 11. It provides a new API for simplified data access. Jakarta Data follows the Repository design pattern for data access, and allows for implementations which may support both SQL and NoSQL data stores.

Getting started

The fastest way to work through this guide is to clone the Git repository and use the projects that are provided inside:

git clone https://github.com/openliberty/guide-jakarta-data.git
cd guide-jakarta-data

The start directory contains the starting project that you will build upon.

The finish directory contains the finished project that you will build.

Before you begin, make sure you have all the necessary prerequisites.

Try what you’ll build

The finish directory in the root of this guide contains the finished application. Give it a try before you proceed.

To try out the application, first go to the finish directory and run the following Maven goal to build the application and deploy it to Open Liberty:

cd finish
mvnw.cmd liberty:run
cd finish
./mvnw liberty:run
cd finish
./mvnw liberty:run

After you see the following message, your Liberty instance is ready:

The defaultServer server is ready to run a smarter planet.

This application allows you to run queries against a set of shipping packages which have a variety of dimensions and destinations. Go to the http://localhost:9080 URL to see all the application data. You can see a column of queries, some of which accept input. To start, find the findAll query with no inputs. Selecting this returns all of the query data similar to the following:

ID  Length  Width   Height  Destination
1   10      20      10      Rochester
2   30      10      10      Austin
3   5       10      5       RTP
4   24      15      6       Rochester
5   15      7       2       Austin
6   8       5       3       Rochester
7   16      3       15      RTP
8   2       15      18      Rochester

You can then try some of the queries which use input to see how it changes which packages are returned. If you find the query named findByLengthGreaterThan and enter 25 in the box labeled length, you can then run the query by clicking the ➜ button. The result looks like the following, with only lengths greater than 25:

ID  Length  Width  Height  Destination
2   30      10	   10      Austin
16  38      16     25      Markham

After you are finished checking out the application, stop the Liberty instance by pressing CTRL+C in the command-line session where you ran Liberty. Alternatively, you can run the liberty:stop goal from the finish directory in another shell session:

mvnw.cmd liberty:stop
./mvnw liberty:stop
./mvnw liberty:stop

Creating an entity and repository

Navigate to the start directory to begin.

When you run Open Liberty in dev mode, dev mode listens for file changes and automatically recompiles and deploys your updates whenever you save a new change. Run the following goal to start Open Liberty in dev mode:

mvnw.cmd liberty:dev
./mvnw liberty:dev
./mvnw liberty:dev

After you see the following message, your Liberty instance is ready in dev mode:

**************************************************************
*    Liberty is running in dev mode.

Dev mode holds your command-line session to listen for file changes. Open another command-line session to continue, or open the project in your editor.

In Jakarta Data an entity defines the structure for persisting a piece of data. This structure is represented by a Java object and its associated fields. The entity used in this guide is a record class called Package.java, which contains a few fields.

Package.java

 1// tag::copyright[]
 2/*******************************************************************************
 3 * Copyright (c) 2024 IBM Corporation and others.
 4 * All rights reserved. This program and the accompanying materials
 5 * are made available under the terms of the Eclipse Public License 2.0
 6 * which accompanies this distribution, and is available at
 7 * http://www.eclipse.org/legal/epl-2.0/
 8 *
 9 * SPDX-License-Identifier: EPL-2.0
10 *******************************************************************************/
11// end::copyright[]
12package io.openliberty.guides.data;
13
14public record Package(int id, float length, float width, float height,
15        String destination) {
16}

Packages.java

  1// tag::copyright[]
  2/*******************************************************************************
  3 * Copyright (c) 2024, 2026 IBM Corporation and others.
  4 * All rights reserved. This program and the accompanying materials
  5 * are made available under the terms of the Eclipse Public License 2.0
  6 * which accompanies this distribution, and is available at
  7 * http://www.eclipse.org/legal/epl-2.0/
  8 *
  9 * SPDX-License-Identifier: EPL-2.0
 10 *******************************************************************************/
 11// end::copyright[]
 12package io.openliberty.guides.data;
 13
 14// tag::query-by-method[]
 15import java.util.List;
 16// end::query-by-method[]
 17
 18import jakarta.data.repository.Repository;
 19import jakarta.data.repository.CrudRepository;
 20// tag::annotations[]
 21import jakarta.data.repository.Find;
 22import jakarta.data.repository.By;
 23import jakarta.data.repository.Insert;
 24import jakarta.data.repository.OrderBy;
 25// end::annotations[]
 26// tag::query-anno[]
 27import jakarta.data.repository.Query;
 28// end::query-anno[]
 29// tag::sorting[]
 30import jakarta.data.Limit;
 31import jakarta.data.Sort;
 32import jakarta.data.page.Page;
 33import jakarta.data.page.PageRequest;
 34// end::sorting[]
 35
 36@Repository
 37// tag::CrudRepository[]
 38public interface Packages extends CrudRepository<Package, Integer> {
 39    // end::CrudRepository[]
 40    // tag::query-by-method[]
 41
 42    // tag::findByLengthGreaterThan[]
 43    List<Package> findByLengthGreaterThan(float length);
 44    // end::findByLengthGreaterThan[]
 45
 46    List<Package> findByLengthGreaterThanAndWidthLessThan(float length, float width);
 47
 48    // tag::findByHeightBetween[]
 49    List<Package> findByHeightBetween(float minHeight, float maxHeight);
 50    // end::findByHeightBetween[]
 51    // end::query-by-method[]
 52    // tag::annotations[]
 53
 54    // tag::Find[]
 55    @Find
 56    // end::Find[]
 57    // tag::getPackagesArrivingIn[]
 58    // tag::By[]
 59    List<Package> getPackagesArrivingIn(@By("destination") String destination);
 60    // end::By[]
 61    // end::getPackagesArrivingIn[]
 62
 63    // tag::Insert[]
 64    @Insert
 65    // end::Insert[]
 66    // tag::add[]
 67    void add(Package p);
 68    // end::add[]
 69
 70    @Find
 71    // tag::OrderBy[]
 72    @OrderBy("height")
 73    // end::OrderBy[]
 74    // tag::sortedByHeightAscending[]
 75    List<Package> sortedByHeightAscending();
 76    // end::sortedByHeightAscending[]
 77    // end::annotations[]
 78    // tag::sorting[]
 79
 80    @Find
 81    // tag::Sort[]
 82    List<Package> sorted(Sort<?> sortBy);
 83    // end::Sort[]
 84
 85    @Find
 86    @OrderBy("length")
 87    // tag::Limit[]
 88    List<Package> shortestWithLimit(Limit limit);
 89    // end::Limit[]
 90
 91    @Find
 92    // tag::Page[]
 93    // tag::PageRequest[]
 94    Page<Package> all(PageRequest pageRequest);
 95    // end::PageRequest[]
 96    // end::Page[]
 97    // end::sorting[]
 98    // tag::query-anno[]
 99
100    // tag::withAnyDimensionLargerThan[]
101    // tag::Query[]
102    @Query("WHERE length > :threshold OR height > :threshold OR width > :threshold")
103    // end::Query[]
104    List<Package> withAnyDimensionLargerThan(float threshold);
105    // end::withAnyDimensionLargerThan[]
106
107    // tag::withTotalDimensionOver[]
108    @Query("WHERE length + width + height > ?1")
109    List<Package> withTotalDimensionOver(float threshold);
110    // end::withTotalDimensionOver[]
111    // end::query-anno[]
112
113}

The repository used in this guide is called Packages.java. Repositories in Jakarta Data provide a simplified means for interacting with persistent data. Jakarta Data’s CrudRepository interface provides built-in methods for Create, Read, Update, and Delete (CRUD) operations, so all you need to add are queries specific to your application’s needs.

For more information on Jakarta Data repositories, see the documentation here: TODO link

Query by Method Name

Query by Method Name allows you to write queries using a descriptive method name following a few intuitive rules on how the method name is structured.

Packages.java

  1// tag::copyright[]
  2/*******************************************************************************
  3 * Copyright (c) 2024, 2026 IBM Corporation and others.
  4 * All rights reserved. This program and the accompanying materials
  5 * are made available under the terms of the Eclipse Public License 2.0
  6 * which accompanies this distribution, and is available at
  7 * http://www.eclipse.org/legal/epl-2.0/
  8 *
  9 * SPDX-License-Identifier: EPL-2.0
 10 *******************************************************************************/
 11// end::copyright[]
 12package io.openliberty.guides.data;
 13
 14// tag::query-by-method[]
 15import java.util.List;
 16// end::query-by-method[]
 17
 18import jakarta.data.repository.Repository;
 19import jakarta.data.repository.CrudRepository;
 20// tag::annotations[]
 21import jakarta.data.repository.Find;
 22import jakarta.data.repository.By;
 23import jakarta.data.repository.Insert;
 24import jakarta.data.repository.OrderBy;
 25// end::annotations[]
 26// tag::query-anno[]
 27import jakarta.data.repository.Query;
 28// end::query-anno[]
 29// tag::sorting[]
 30import jakarta.data.Limit;
 31import jakarta.data.Sort;
 32import jakarta.data.page.Page;
 33import jakarta.data.page.PageRequest;
 34// end::sorting[]
 35
 36@Repository
 37// tag::CrudRepository[]
 38public interface Packages extends CrudRepository<Package, Integer> {
 39    // end::CrudRepository[]
 40    // tag::query-by-method[]
 41
 42    // tag::findByLengthGreaterThan[]
 43    List<Package> findByLengthGreaterThan(float length);
 44    // end::findByLengthGreaterThan[]
 45
 46    List<Package> findByLengthGreaterThanAndWidthLessThan(float length, float width);
 47
 48    // tag::findByHeightBetween[]
 49    List<Package> findByHeightBetween(float minHeight, float maxHeight);
 50    // end::findByHeightBetween[]
 51    // end::query-by-method[]
 52    // tag::annotations[]
 53
 54    // tag::Find[]
 55    @Find
 56    // end::Find[]
 57    // tag::getPackagesArrivingIn[]
 58    // tag::By[]
 59    List<Package> getPackagesArrivingIn(@By("destination") String destination);
 60    // end::By[]
 61    // end::getPackagesArrivingIn[]
 62
 63    // tag::Insert[]
 64    @Insert
 65    // end::Insert[]
 66    // tag::add[]
 67    void add(Package p);
 68    // end::add[]
 69
 70    @Find
 71    // tag::OrderBy[]
 72    @OrderBy("height")
 73    // end::OrderBy[]
 74    // tag::sortedByHeightAscending[]
 75    List<Package> sortedByHeightAscending();
 76    // end::sortedByHeightAscending[]
 77    // end::annotations[]
 78    // tag::sorting[]
 79
 80    @Find
 81    // tag::Sort[]
 82    List<Package> sorted(Sort<?> sortBy);
 83    // end::Sort[]
 84
 85    @Find
 86    @OrderBy("length")
 87    // tag::Limit[]
 88    List<Package> shortestWithLimit(Limit limit);
 89    // end::Limit[]
 90
 91    @Find
 92    // tag::Page[]
 93    // tag::PageRequest[]
 94    Page<Package> all(PageRequest pageRequest);
 95    // end::PageRequest[]
 96    // end::Page[]
 97    // end::sorting[]
 98    // tag::query-anno[]
 99
100    // tag::withAnyDimensionLargerThan[]
101    // tag::Query[]
102    @Query("WHERE length > :threshold OR height > :threshold OR width > :threshold")
103    // end::Query[]
104    List<Package> withAnyDimensionLargerThan(float threshold);
105    // end::withAnyDimensionLargerThan[]
106
107    // tag::withTotalDimensionOver[]
108    @Query("WHERE length + width + height > ?1")
109    List<Package> withTotalDimensionOver(float threshold);
110    // end::withTotalDimensionOver[]
111    // end::query-anno[]
112
113}
Update the Packages.java class.
src/main/java/io/openliberty/guides/data/Packages.java

This allows methods like findByLengthGreaterThan(float length) or findByHeightBetween(float minHeight, float maxHeight) to automatically be turned into queries.

The findByLengthGreaterThan method finds packages where the length exceeds the value you provide. If you pass 15, it returns packages with lengths greater than 15 from the sample data. The findByHeightBetween method finds packages within a specific height range. If you pass 5 and 15, it returns packages with heights between 5 and 15, inclusive.

For more information see the JavaDoc section on Query by Method Name

Because you are running the application in dev mode, your changes are automatically picked up. Refresh the application in your browser at http://localhost:9080 to see the new queries you just added. Try out the findByLengthGreaterThan query by entering different length values, or experiment with the findByHeightBetween query by providing minimum and maximum height values.

Now that you have seen how Query by Method Name works, try creating your own queries following the same pattern. Here are some ideas to get you started:

  • Find all packages going to a specific destination

  • Find packages narrower than a specified width

Querying with method annotations

Queries can also be written using method annotations. This allows for additional flexibility in the queries as well as the method names.

Packages.java

  1// tag::copyright[]
  2/*******************************************************************************
  3 * Copyright (c) 2024, 2026 IBM Corporation and others.
  4 * All rights reserved. This program and the accompanying materials
  5 * are made available under the terms of the Eclipse Public License 2.0
  6 * which accompanies this distribution, and is available at
  7 * http://www.eclipse.org/legal/epl-2.0/
  8 *
  9 * SPDX-License-Identifier: EPL-2.0
 10 *******************************************************************************/
 11// end::copyright[]
 12package io.openliberty.guides.data;
 13
 14// tag::query-by-method[]
 15import java.util.List;
 16// end::query-by-method[]
 17
 18import jakarta.data.repository.Repository;
 19import jakarta.data.repository.CrudRepository;
 20// tag::annotations[]
 21import jakarta.data.repository.Find;
 22import jakarta.data.repository.By;
 23import jakarta.data.repository.Insert;
 24import jakarta.data.repository.OrderBy;
 25// end::annotations[]
 26// tag::query-anno[]
 27import jakarta.data.repository.Query;
 28// end::query-anno[]
 29// tag::sorting[]
 30import jakarta.data.Limit;
 31import jakarta.data.Sort;
 32import jakarta.data.page.Page;
 33import jakarta.data.page.PageRequest;
 34// end::sorting[]
 35
 36@Repository
 37// tag::CrudRepository[]
 38public interface Packages extends CrudRepository<Package, Integer> {
 39    // end::CrudRepository[]
 40    // tag::query-by-method[]
 41
 42    // tag::findByLengthGreaterThan[]
 43    List<Package> findByLengthGreaterThan(float length);
 44    // end::findByLengthGreaterThan[]
 45
 46    List<Package> findByLengthGreaterThanAndWidthLessThan(float length, float width);
 47
 48    // tag::findByHeightBetween[]
 49    List<Package> findByHeightBetween(float minHeight, float maxHeight);
 50    // end::findByHeightBetween[]
 51    // end::query-by-method[]
 52    // tag::annotations[]
 53
 54    // tag::Find[]
 55    @Find
 56    // end::Find[]
 57    // tag::getPackagesArrivingIn[]
 58    // tag::By[]
 59    List<Package> getPackagesArrivingIn(@By("destination") String destination);
 60    // end::By[]
 61    // end::getPackagesArrivingIn[]
 62
 63    // tag::Insert[]
 64    @Insert
 65    // end::Insert[]
 66    // tag::add[]
 67    void add(Package p);
 68    // end::add[]
 69
 70    @Find
 71    // tag::OrderBy[]
 72    @OrderBy("height")
 73    // end::OrderBy[]
 74    // tag::sortedByHeightAscending[]
 75    List<Package> sortedByHeightAscending();
 76    // end::sortedByHeightAscending[]
 77    // end::annotations[]
 78    // tag::sorting[]
 79
 80    @Find
 81    // tag::Sort[]
 82    List<Package> sorted(Sort<?> sortBy);
 83    // end::Sort[]
 84
 85    @Find
 86    @OrderBy("length")
 87    // tag::Limit[]
 88    List<Package> shortestWithLimit(Limit limit);
 89    // end::Limit[]
 90
 91    @Find
 92    // tag::Page[]
 93    // tag::PageRequest[]
 94    Page<Package> all(PageRequest pageRequest);
 95    // end::PageRequest[]
 96    // end::Page[]
 97    // end::sorting[]
 98    // tag::query-anno[]
 99
100    // tag::withAnyDimensionLargerThan[]
101    // tag::Query[]
102    @Query("WHERE length > :threshold OR height > :threshold OR width > :threshold")
103    // end::Query[]
104    List<Package> withAnyDimensionLargerThan(float threshold);
105    // end::withAnyDimensionLargerThan[]
106
107    // tag::withTotalDimensionOver[]
108    @Query("WHERE length + width + height > ?1")
109    List<Package> withTotalDimensionOver(float threshold);
110    // end::withTotalDimensionOver[]
111    // end::query-anno[]
112
113}
Update the Packages.java class.
src/main/java/io/openliberty/guides/data/Packages.java

The @Find and @By annotations

The @Find annotation indicates that a method is a query which may return entities. Used in isolation it returns all entities, but by using the @By annotation, it can be limited to entities which match the value provided at runtime. The getPackagesArrivingIn method demonstrates using the @Find and @By annotations to return all packages that are destined for a specific location.

For example, when you call this method with Rochester, it returns the 6 packages from the sample data that are going to Rochester.

Renaming provided methods

If a method name provided by a built in Jakarta Data repository class doesn’t align with your repository you can use annotations to provide your own method. For example, using the @Insert annotation you can create a method named add instead of the insert method inherited from CrudRepository.

The @OrderBy annotation

To provide ordering annotatively, you can use the @OrderBy annotation. The default ordering direction is ascending. The sortedByHeightAscending method demonstrates how to obtain all of the packages in the repository sorted by the height parameter.

This returns all packages ordered from shortest to tallest, starting with the package with height 2, then 3, and so on up to the tallest package with height 25.

Refresh the application in your browser to see the new queries you just added. Try out the getPackagesArrivingIn query by entering different destination names, or experiment with the sortedByHeightAscending query to see the packages ordered by height.

Now that you have seen how to use annotations for queries, try creating your own annotated methods. Here are some ideas to get you started:

  • Find packages with a specific width using @Find and @By

  • Create a method that returns packages ordered by length

Sorting, limiting, and paginating results

Jakarta Data provides the Sort and Limit classes to create queries which can be modified at runtime. It also includes a mechanism for pagination to better handle large sets of results.

Packages.java

  1// tag::copyright[]
  2/*******************************************************************************
  3 * Copyright (c) 2024, 2026 IBM Corporation and others.
  4 * All rights reserved. This program and the accompanying materials
  5 * are made available under the terms of the Eclipse Public License 2.0
  6 * which accompanies this distribution, and is available at
  7 * http://www.eclipse.org/legal/epl-2.0/
  8 *
  9 * SPDX-License-Identifier: EPL-2.0
 10 *******************************************************************************/
 11// end::copyright[]
 12package io.openliberty.guides.data;
 13
 14// tag::query-by-method[]
 15import java.util.List;
 16// end::query-by-method[]
 17
 18import jakarta.data.repository.Repository;
 19import jakarta.data.repository.CrudRepository;
 20// tag::annotations[]
 21import jakarta.data.repository.Find;
 22import jakarta.data.repository.By;
 23import jakarta.data.repository.Insert;
 24import jakarta.data.repository.OrderBy;
 25// end::annotations[]
 26// tag::query-anno[]
 27import jakarta.data.repository.Query;
 28// end::query-anno[]
 29// tag::sorting[]
 30import jakarta.data.Limit;
 31import jakarta.data.Sort;
 32import jakarta.data.page.Page;
 33import jakarta.data.page.PageRequest;
 34// end::sorting[]
 35
 36@Repository
 37// tag::CrudRepository[]
 38public interface Packages extends CrudRepository<Package, Integer> {
 39    // end::CrudRepository[]
 40    // tag::query-by-method[]
 41
 42    // tag::findByLengthGreaterThan[]
 43    List<Package> findByLengthGreaterThan(float length);
 44    // end::findByLengthGreaterThan[]
 45
 46    List<Package> findByLengthGreaterThanAndWidthLessThan(float length, float width);
 47
 48    // tag::findByHeightBetween[]
 49    List<Package> findByHeightBetween(float minHeight, float maxHeight);
 50    // end::findByHeightBetween[]
 51    // end::query-by-method[]
 52    // tag::annotations[]
 53
 54    // tag::Find[]
 55    @Find
 56    // end::Find[]
 57    // tag::getPackagesArrivingIn[]
 58    // tag::By[]
 59    List<Package> getPackagesArrivingIn(@By("destination") String destination);
 60    // end::By[]
 61    // end::getPackagesArrivingIn[]
 62
 63    // tag::Insert[]
 64    @Insert
 65    // end::Insert[]
 66    // tag::add[]
 67    void add(Package p);
 68    // end::add[]
 69
 70    @Find
 71    // tag::OrderBy[]
 72    @OrderBy("height")
 73    // end::OrderBy[]
 74    // tag::sortedByHeightAscending[]
 75    List<Package> sortedByHeightAscending();
 76    // end::sortedByHeightAscending[]
 77    // end::annotations[]
 78    // tag::sorting[]
 79
 80    @Find
 81    // tag::Sort[]
 82    List<Package> sorted(Sort<?> sortBy);
 83    // end::Sort[]
 84
 85    @Find
 86    @OrderBy("length")
 87    // tag::Limit[]
 88    List<Package> shortestWithLimit(Limit limit);
 89    // end::Limit[]
 90
 91    @Find
 92    // tag::Page[]
 93    // tag::PageRequest[]
 94    Page<Package> all(PageRequest pageRequest);
 95    // end::PageRequest[]
 96    // end::Page[]
 97    // end::sorting[]
 98    // tag::query-anno[]
 99
100    // tag::withAnyDimensionLargerThan[]
101    // tag::Query[]
102    @Query("WHERE length > :threshold OR height > :threshold OR width > :threshold")
103    // end::Query[]
104    List<Package> withAnyDimensionLargerThan(float threshold);
105    // end::withAnyDimensionLargerThan[]
106
107    // tag::withTotalDimensionOver[]
108    @Query("WHERE length + width + height > ?1")
109    List<Package> withTotalDimensionOver(float threshold);
110    // end::withTotalDimensionOver[]
111    // end::query-anno[]
112
113}
Update the Packages.java class.
src/main/java/io/openliberty/guides/data/Packages.java

Sort

In addition to the @OrderBy annotation it is possible to provide sorting at runtime. This is accomplished by adding a Sort parameter to your query method like in the sorted method.

For example, you can sort by length to see packages from shortest (#2) to longest (#38), or sort by destination to see them alphabetically (Austin, Markham, RTP, Rochester).

Limit

Jakarta Data queries can restrict the number of entities returned at runtime by providing a Limit object to the query as shown in the shortestWithLimit method.

This method returns the shortest packages in order from shortest to longest, but limited to only the specified number of results. For example, if you pass Limit.of(3), it returns only the 3 shortest packages (with heights of 2, 3, and 5).

Paging

When querying large amounts of data, paging is possible by adding a PageRequest parameter to your query method like in the all method. This method returns all of the packages, but with the results paginated based on the provided PageRequest.

For example, PageRequest.ofSize(5) returns the first 5 packages, and you can request subsequent pages to see the remaining packages from the sample data.

Refresh the application in your browser to see the new queries you just added. Try out the sorted query by providing different sort parameters, or experiment with the shortestWithLimit query to see how limiting affects the results.

Now that you have seen how sorting, limiting, and paginating work, try creating your own queries using these features. Here are some ideas to get you started:

  • Find packages going to a specific destination with sorting

  • Get a limited number of the widest packages

  • Create a paginated query for packages by destination

The Query Annotation

The @Query annotation allows users to write queries using the Jakarta Data Query Language (JDQL). Complex queries can be written concisely using JDQL. JDQL is a strict subset of the Jakarta Persistence Query Language (JPQL).

Packages.java

  1// tag::copyright[]
  2/*******************************************************************************
  3 * Copyright (c) 2024, 2026 IBM Corporation and others.
  4 * All rights reserved. This program and the accompanying materials
  5 * are made available under the terms of the Eclipse Public License 2.0
  6 * which accompanies this distribution, and is available at
  7 * http://www.eclipse.org/legal/epl-2.0/
  8 *
  9 * SPDX-License-Identifier: EPL-2.0
 10 *******************************************************************************/
 11// end::copyright[]
 12package io.openliberty.guides.data;
 13
 14// tag::query-by-method[]
 15import java.util.List;
 16// end::query-by-method[]
 17
 18import jakarta.data.repository.Repository;
 19import jakarta.data.repository.CrudRepository;
 20// tag::annotations[]
 21import jakarta.data.repository.Find;
 22import jakarta.data.repository.By;
 23import jakarta.data.repository.Insert;
 24import jakarta.data.repository.OrderBy;
 25// end::annotations[]
 26// tag::query-anno[]
 27import jakarta.data.repository.Query;
 28// end::query-anno[]
 29// tag::sorting[]
 30import jakarta.data.Limit;
 31import jakarta.data.Sort;
 32import jakarta.data.page.Page;
 33import jakarta.data.page.PageRequest;
 34// end::sorting[]
 35
 36@Repository
 37// tag::CrudRepository[]
 38public interface Packages extends CrudRepository<Package, Integer> {
 39    // end::CrudRepository[]
 40    // tag::query-by-method[]
 41
 42    // tag::findByLengthGreaterThan[]
 43    List<Package> findByLengthGreaterThan(float length);
 44    // end::findByLengthGreaterThan[]
 45
 46    List<Package> findByLengthGreaterThanAndWidthLessThan(float length, float width);
 47
 48    // tag::findByHeightBetween[]
 49    List<Package> findByHeightBetween(float minHeight, float maxHeight);
 50    // end::findByHeightBetween[]
 51    // end::query-by-method[]
 52    // tag::annotations[]
 53
 54    // tag::Find[]
 55    @Find
 56    // end::Find[]
 57    // tag::getPackagesArrivingIn[]
 58    // tag::By[]
 59    List<Package> getPackagesArrivingIn(@By("destination") String destination);
 60    // end::By[]
 61    // end::getPackagesArrivingIn[]
 62
 63    // tag::Insert[]
 64    @Insert
 65    // end::Insert[]
 66    // tag::add[]
 67    void add(Package p);
 68    // end::add[]
 69
 70    @Find
 71    // tag::OrderBy[]
 72    @OrderBy("height")
 73    // end::OrderBy[]
 74    // tag::sortedByHeightAscending[]
 75    List<Package> sortedByHeightAscending();
 76    // end::sortedByHeightAscending[]
 77    // end::annotations[]
 78    // tag::sorting[]
 79
 80    @Find
 81    // tag::Sort[]
 82    List<Package> sorted(Sort<?> sortBy);
 83    // end::Sort[]
 84
 85    @Find
 86    @OrderBy("length")
 87    // tag::Limit[]
 88    List<Package> shortestWithLimit(Limit limit);
 89    // end::Limit[]
 90
 91    @Find
 92    // tag::Page[]
 93    // tag::PageRequest[]
 94    Page<Package> all(PageRequest pageRequest);
 95    // end::PageRequest[]
 96    // end::Page[]
 97    // end::sorting[]
 98    // tag::query-anno[]
 99
100    // tag::withAnyDimensionLargerThan[]
101    // tag::Query[]
102    @Query("WHERE length > :threshold OR height > :threshold OR width > :threshold")
103    // end::Query[]
104    List<Package> withAnyDimensionLargerThan(float threshold);
105    // end::withAnyDimensionLargerThan[]
106
107    // tag::withTotalDimensionOver[]
108    @Query("WHERE length + width + height > ?1")
109    List<Package> withTotalDimensionOver(float threshold);
110    // end::withTotalDimensionOver[]
111    // end::query-anno[]
112
113}
Update the Packages.java class.
src/main/java/io/openliberty/guides/data/Packages.java

For an example of a complex query simplified using JDQL, take a look at withAnyDimensionLargerThan.

This query checks for packages where the length, height, or width are larger than a threshold, which is provided as a parameter in the function. The threshold parameter is referenced in the query using :threshold. Achieving the same query with Query by Method Name would result in a very long method name and additional parameters.

For example, if you pass 20, it returns packages where at least one dimension exceeds 20, such as package #2 (length 30) or package #16 (length 38, height 25).

The withTotalDimensionOver query sums the length, width, and height of each package to check if the total exceeds a provided threshold. This query uses positional parameter syntax with ?1 to reference the first method parameter.

For example, passing 50 returns packages where length + width + height > 50. Package #16 (38 + 16 + 25 = 79) would be included in the results.

See the Javadoc for the Query Annotation for more information on JDQL.

Where to next?

Experiment by creating your own queries. Use the existing ones in the Packages class as a starting point and then test them out in the sample application. For example, you could add a query to find packages arriving at a specific destination, which is ordered by width:

    @Find
    @OrderBy("width")
    List<Package> byWidthArrivingIn(@By("destination") String destination);
Copy file contents
Copied to clipboard

Prerequisites:

Great work! You're done!

What did you think of this guide?

Extreme Dislike Dislike Like Extreme Like

What could make this guide better?

Raise an issue to share feedback

Create a pull request to contribute to this guide

Need help?

Ask a question on Stack Overflow

Like Open Liberty? Star our repo on GitHub.

Star

Guide license

Where to next?