Interface Template
Template is a helper class that increases
productivity when performing common NoSQL operations. The Template
feature in Jakarta NoSQL simplifies the implementation of common
database operations by providing a basic API to the underlying
persistence engine. It follows the standard DAO (Data Access
Object) pattern, a common design pattern used in software
development.
The Template pattern involves creating a skeletal structure for an algorithm, with some steps implemented and others left to be implemented by subclasses. Similarly, the Template feature in Jakarta NoSQL makes a skeleton around NoSQL database operations, allowing developers to focus on implementing the specific logic required for their application.
Overall, the Template feature in Jakarta NoSQL provides a simple and efficient way to implement common database operations while following established design patterns like the Template Method. By using the Template feature, developers can save time and effort in implementing their NoSQL database operations, allowing them to focus on other aspects of their application.
@Inject
Template template;
Book book = Book.builder()
.id(id)
.title("Java Concurrency in Practice")
.author("Brian Goetz")
.year(Year.of(2006))
.edition(1)
.build();
template.insert(book);
Optional<Book> optional = template.find(Book.class, id);
System.out.println("The result " + optional);
template.delete(Book.class,id);
Furthermore, in CRUD (Create, Read, Update, Delete) operations,
Template provides a fluent API for selecting, deleting, and
querying entities, offering the ability to search and remove
beyond the ID attribute. Take a look at
QueryMapper
for more detail about the provided fluent-API.
@Inject
Template template;
List<Book> books = template.select(Book.class)
.where("author")
.eq("Joshua Bloch")
.and("edition")
.gt(3)
.results();
Stream<Book> books = template.select(Book.class)
.where("author")
.eq("Joshua Bloch")
.stream();
Optional<Book> optional = template.select(Book.class)
.where("title")
.eq("Java Concurrency in Practice")
.and("author")
.eq("Brian Goetz")
.and("year")
.eq(Year.of(2006))
.singleResult();
template.delete(Book.class)
.where("author")
.eq("Joshua Bloch")
.and("edition")
.gt(3)
.execute();
- Since:
- 1.0.0
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionStart a query builder using the fluent API.<T,K> void Deletes by ID or key.<T> voidDeletes the given entities.<T> voiddelete(T entity) Deletes a given entity.<T,K> Optional <T> Retrieves an entity by its Id.<T> Iterable<T> Inserts multiple entities into the database.<T> Iterable<T> Inserts multiple entities into the database with the expiration date.<T> Tinsert(T entity) Inserts an entity into the database.<T> TInserts an entity into the database with an expiration to the entity.Creates a query from a raw string using Jakarta Common Query Language (JCQL).Start a query using the fluent API.<T> TypedQuery<T> typedQuery(String query, Class<T> type) Creates aTypedQueryusing the given query string and result type.Start an update builder using the fluent API.<T> Iterable<T> Modifies entities that already exist in the database.<T> Tupdate(T entity) Modifies an entity that already exists in the database.
-
Method Details
-
insert
<T> T insert(T entity) Inserts an entity into the database. If an entity of this type with the same unique identifier already exists in the database and the database supports ACID transactions, then this method raises an error. In databases that follow the BASE model or use an append model to write data, this exception is not thrown.The entity instance returned as a result of this method must include all values written to the database, including all automatically generated values and incremented values that changed due to the insert. After invoking this method, do not continue to use the instance supplied as a parameter. This method makes no guarantees about the state of the instance that is supplied as a parameter.
@Inject Template template; Book book = new Book("978-0132350884", "Clean Code", "Robert C. Martin"); Book insertedBook = template.insert(book);- Type Parameters:
-
T- the entity type - Parameters:
-
entity- the entity to insert. Must not benull. - Returns:
- the inserted entity, which may or may not be a different instance depending on whether the insert caused values to be generated or automatically incremented.
- Throws:
-
NullPointerException- if the entity is null.
-
insert
Inserts an entity into the database with an expiration to the entity. If an entity of this type with the same unique identifier already exists in the database and the database supports ACID transactions, then this method raises an error. In databases that follow the BASE model or use an append model to write data, this exception is not thrown.The entity instance returned as a result of this method must include all values written to the database, including all automatically generated values and incremented values that changed due to the insert. After invoking this method, do not continue to use the instance supplied as a parameter. This method makes no guarantees about the state of the instance that is supplied as a parameter.
Time-To-Live (TTL) is a feature provided by some NoSQL databases where data is automatically removed from the database after a specified duration. When inserting an entity with a TTL, the entity will be automatically deleted from the database after the specified duration has passed since its insertion. If the database does not support TTL or if the TTL feature is not enabled, this operation will not have any effect on the entity's expiration.
@Inject Template template; SessionToken token = new SessionToken("abc123", "user-42", Instant.now()); Duration ttl = Duration.ofMinutes(30); SessionToken inserted = template.insert(token, ttl);- Type Parameters:
-
T- the entity type - Parameters:
-
entity- the entity to insert. Must not benull. ttl- time to live- Returns:
- the inserted entity, which may or may not be a different instance depending on whether the insert caused values to be generated or automatically incremented.
- Throws:
-
NullPointerException- if the entity is null. -
UnsupportedOperationException- when the database does not provide TTL
-
insert
Inserts multiple entities into the database. If any entity of this type with the same unique identifier as any of the given entities already exists in the database and the database supports ACID transactions, then this method raises an error. In databases that follow the BASE model or use an append model to write data, this exception is not thrown.The entities within the returned
Iterablemust include all values written to the database, including all automatically generated values and incremented values that changed due to the insert. After invoking this method, do not continue to use the entity instances that are supplied in the parameter. This method makes no guarantees about the state of the entity instances that are supplied in the parameter. The position of entities within theIterablereturn value must correspond to the position of entities in the parameter based on the unique identifier of the entity.- Type Parameters:
-
T- the entity type - Parameters:
entities- entities to insert.- Returns:
- an iterable containing the inserted entities, which may or may not be different instances depending on whether the insert caused values to be generated or automatically incremented.
- Throws:
-
NullPointerException- if the iterable is null or any element is null.
-
insert
Inserts multiple entities into the database with the expiration date. If any entity of this type with the same unique identifier as any of the given entities already exists in the database and the database supports ACID transactions, then this method raises an error. In databases that follow the BASE model or use an append model to write data, this exception is not thrown.The entities within the returned
Iterablemust include all values written to the database, including all automatically generated values and incremented values that changed due to the insert. After invoking this method, do not continue to use the entity instances that are supplied in the parameter. This method makes no guarantees about the state of the entity instances that are supplied in the parameter. The position of entities within theIterablereturn value must correspond to the position of entities in the parameter based on the unique identifier of the entity.Time-To-Live (TTL) is a feature provided by some NoSQL databases where data is automatically removed from the database after a specified duration. When inserting entities with a TTL, the entities will be automatically deleted from the database after the specified duration has passed since their insertion. If the database does not support TTL or if the TTL feature is not enabled, this operation will not have any effect on the expiration of the entities.
@Inject Template template; List<SessionToken> tokens = List.of( SessionToken.builder() .id("abc123") .userId("user-42") .issuedAt(Instant.now()) .build(), SessionToken.builder() .id("def456") .userId("user-99") .issuedAt(Instant.now()) .build() ); Iterable<SessionToken> insertedTokens = template.insert(tokens);- Type Parameters:
-
T- the entity type - Parameters:
entities- entities to insert.ttl- time to live- Returns:
- an iterable containing the inserted entities, which may or may not be different instances depending on whether the insert caused values to be generated or automatically incremented.
- Throws:
-
NullPointerException- if the iterable is null or any element is null. -
UnsupportedOperationException- if the database does not provide time-to-live for insert operations.
-
update
<T> T update(T entity) Modifies an entity that already exists in the database.For an update to be made, a matching entity with the same unique identifier must be present in the database. In databases that use an append model to write data or follow the BASE model, this method behaves the same as the
insert(T)method.If the entity is versioned (for example, with an annotation or by another convention from the entity model such as having an attribute named
version), then the version must also match. The version is automatically incremented when making the update.Non-matching entities are ignored and do not cause an error to be raised.
@Inject Template template; Book book = Book.builder() .isbn("978-1234567890") .title("Domain-Driven Design") .version(1) .build(); Book updated = template.update(book);- Type Parameters:
-
T- the entity type - Parameters:
-
entity- the entity to update. Must not benull. - Returns:
- the updated entity, which may or may not be a different instance depending on whether the update caused values to be generated or automatically incremented.
- Throws:
-
NullPointerException- if the entity is null.
-
update
Modifies entities that already exist in the database.For an update to be made to an entity, a matching entity with the same unique identifier must be present in the database. In databases that use an append model to write data or follow the BASE model, this method behaves the same as the
insert(Iterable)method.If the entity is versioned (for example, with an annotation or by another convention from the entity model such as having an attribute named
version), then the version must also match. The version is automatically incremented when making the update.Non-matching entities are ignored and do not cause an error to be raised.
@Inject Template template; List<Book> booksToUpdate = List.of( Book.builder().isbn("978-1111111111").title("Effective Java").version(1).build(), Book.builder().isbn("978-2222222222").title("Clean Code").version(2).build() ); Iterable<Book> updatedBooks = template.update(booksToUpdate);- Type Parameters:
-
T- the entity class type - Parameters:
entities- entities to update.- Returns:
- the number of matching entities that were found in the database to update.
- Throws:
-
NullPointerException- if either the iterable is null or any element is null.
-
delete
<T> void delete(T entity) Deletes a given entity. Deletion is performed by matching the Id, and if the entity is versioned (for example, withjakarta.persistence.Version), then also the version. Other attributes of the entity do not need to match.@Inject Template template; SessionToken token = SessionToken.builder() .token("abc123") .userId("user-42") .version(1) .build(); template.delete(token);- Type Parameters:
-
T- the entity type - Parameters:
-
entity- must not benull. - Throws:
-
NullPointerException- when the entity is null
-
delete
Deletes the given entities. Deletion of each entity is performed by matching the unique identifier, and if the entity is versioned (for example, withjakarta.persistence.Version), then also the version. Other attributes of the entity do not need to match.@Inject Template template; List<SessionToken> tokens = List.of( SessionToken.builder() .token("abc123") .userId("user-42") .version(1) .build(), SessionToken.builder() .token("def456") .userId("user-99") .version(2) .build() ); template.delete(tokens);- Type Parameters:
-
T- the entity type - Parameters:
-
entities- Must not benull. Must not containnullelements. - Throws:
-
NullPointerException- If the iterable isnullor containsnullelements.
-
find
Retrieves an entity by its Id.Example usage:
@Inject Template template; Optional<SessionToken> token = template.find(SessionToken.class, "abc123");- Type Parameters:
-
T- the entity class type -
K- the id type - Parameters:
type- the entity classid- the id value- Returns:
-
the entity instance, otherwise
Optional.empty() - Throws:
-
NullPointerException- when either the type or id are null
-
delete
Deletes by ID or key.@Inject Template template; template.delete(SessionToken.class, "abc123");- Type Parameters:
-
T- the entity class type -
K- the id type - Parameters:
type- the entity classid- the id value- Throws:
-
NullPointerException- when either the type or id are null
-
select
Start a query using the fluent API. The return value is a mutable and non-thread-safe instance.@Inject Template template; List<Person> results = template.select(Person.class) .where("name").eq("Ada") .and("age").gte(30) .orderBy("age").asc() .limit(10) .result();- Type Parameters:
-
T- the entity type - Parameters:
type- the entity class- Returns:
-
a
QueryMapper.MapperFrominstance - Throws:
-
NullPointerException- when type is null -
UnsupportedOperationException- when the database cannot operate, such as key-value where most operations are key-based.
-
delete
Start a query builder using the fluent API. The returned value is a mutable and non-thread-safe instance.@Inject Template template; template.delete(Book.class) .where("author").eq("Ada") .and("publishedYear").gte(2020) .execute();- Type Parameters:
-
T- the entity type - Parameters:
type- the entity class- Returns:
-
a
QueryMapper.MapperDeleteFrominstance - Throws:
-
NullPointerException- when type is null -
UnsupportedOperationException- when the database cannot operate, such as key-value where most operations are key-based.
-
update
Start an update builder using the fluent API. The returned value is a mutable and non-thread-safe instance.
This operation updates matching entities based on the defined predicates. The update semantics and supported operations depend on the underlying database.@Inject Template template; template.update(Book.class) .set("title").to("Domain-Driven Design with Java") .set("publishedYear").to(2025) .where("author").eq("Ada") .execute();- Type Parameters:
-
T- the entity type - Parameters:
type- the entity class- Returns:
-
a
QueryMapper.MapperUpdateFrominstance - Throws:
-
NullPointerException- when type is null -
UnsupportedOperationException- when the database cannot operate, such as key-value stores that only support key-based updates.
-
query
Creates a query from a raw string using Jakarta Common Query Language (JCQL).The entity type is inferred from the query string (e.g.,
FROM Person), so no result class needs to be explicitly passed.The returned
Queryinstance is mutable and not thread-safe.Example usage:
Query query = template.query("SELECT * FROM Person WHERE name = :name"); List<Person> people = query.bind("name", "Ada").result();- Parameters:
-
query- the Jakarta Common Query Language (JCQL) string to execute (e.g.,SELECT * FROM Person WHERE active = true) - Returns:
-
a new
Queryinstance bound to this query string - Throws:
-
NullPointerException- if the query string isnull -
UnsupportedOperationException- if the database does not support dynamic queries - Since:
- 1.1.0
-
typedQuery
Creates aTypedQueryusing the given query string and result type.This method provides a type-safe way to execute queries by explicitly specifying the expected result type. The provided
typemust be one of the following:-
An entity class annotated with
@Entity. The query may explicitly include aFROMclause, or omit it if the entity can be inferred from thetypeparameter. -
A Java
recordannotated with@Projection, which maps partial or flattened results based on the query output.
When using a projection, the query can omit the
SELECTclause entirely if the record component names match the entity’s attributes. TheFROMclause can also be omitted if theProjection.from()attribute is specified.If the query references a different entity than the one implied by the
typeargument, anIllegalArgumentExceptionmay be thrown by the provider to indicate a mismatch.This method returns a
TypedQuery, which improves safety and readability by:-
Restricting the result type to
T, eliminating the need for casting - Allowing fluent parameter binding and result handling
List<TechProductView> techProducts = template .typedQuery("FROM Product WHERE category = 'TECH'", TechProductView.class) .result(); Optional<PromotionalProduct> promo = template .typedQuery("WHERE price < :maxPrice", PromotionalProduct.class) .bind("maxPrice", 100) .singleResult();- Type Parameters:
-
T- the type of the result - Parameters:
-
query- the query string using Jakarta Common Query Language (JCQL) -
type- the expected result type (entity or projection class) - Returns:
-
a
TypedQueryinstance to bind parameters and fetch results - Throws:
-
NullPointerException- if the query or type isnull -
IllegalArgumentException- if the providedtypeis incompatible with the entity in the query -
UnsupportedOperationException- if the query is not supported by the underlying provider - Since:
- 1.1.0
-
An entity class annotated with
-