Module jakarta.data
Jakarta Data standardizes a programming model where data is represented by simple Java classes and where operations on data are represented by interface methods.
The application defines simple Java objects called entities to represent data in the database. Fields or accessor methods designate each entity property. For example,
@Entity public class Product { @Id public long id; public String name; public float price; public int yearProduced; ... }
A repository is an interface annotated with the Repository
annotation.
A repository declares methods which perform queries and other operations on entities.
For example,
@Repository public interface Products extends BasicRepository<Product, Long> { @Insert void create(Product prod); @OrderBy("price") List<Product> findByNameIgnoreCaseLikeAndPriceLessThan(String namePattern, float max); @Query("UPDATE Product SET price = price * (1.0 - ?1) WHERE yearProduced <= ?2") int discountOldInventory(float rateOfDiscount, int maxYear); ... }
Repository interfaces are implemented by the container/runtime and are made
available to applications via the jakarta.inject.Inject
annotation. For
example,
@Inject Products products; ... products.create(newProduct); found = products.findByNameIgnoreCaseLikeAndPriceLessThan("%cell%phone%", 900.0f); numDiscounted = products.discountOldInventory(0.15f, Year.now().getValue() - 1);
Jakarta Persistence and Jakarta NoSQL define programming models for entity classes that may be used with Jakarta Data:
jakarta.persistence.Entity
and the corresponding entity-related annotations of the Jakarta Persistence specification may be used to define entities stored in a relational database, orjakarta.nosql.Entity
and the corresponding entity-related annotations of the Jakarta NoSQL specification may be used to define entities stored in a NoSQL database.
A Jakarta Data provider may define its own programming model for entity classes representing some other arbitrary kind of data.
Methods of repository interfaces must be styled according to a well-defined set of conventions, which instruct the container/runtime about the desired data access operation to perform. These conventions consist of patterns of reserved keywords within the method name, method parameters with special meaning, method return types, and annotations placed upon the method and its parameters.
Built-in repository superinterfaces, such as DataRepository
,
are provided as a convenient way to inherit commonly used methods and
are parameterized by the entity type and by its id type. Other built-in
repository interfaces, such as BasicRepository
, may be used in
place of DataRepository
and provide a base set of predefined
repository operations serving as an optional starting point. The Java
application programmer may extend these built-in interfaces, adding
custom methods. Alternatively, the programmer may define a repository
interface without inheriting the built-in superinterfaces. A programmer
may even copy individual method signatures from the built-in repositories
to a repository which does not inherit any built-in superinterface. This
is possible because the methods of the built-in repository superinterfaces
respect the conventions defined for custom repository methods.
The following example shows an entity class, an embeddable class, and a repository interface:
@Entity public class Purchase { @Id public String purchaseId; @Embedded public Address address; ... } @Embeddable public class Address { public int zipCode; ... } @Repository public interface Purchases { @OrderBy("address.zipCode") List<Purchase> findByAddressZipCodeIn(List<Integer> zipCodes); @Query("WHERE address.zipCode = ?1") List<Purchase> forZipCode(int zipCode); @Save Purchase checkout(Purchase purchase); }
Entities
An entity programming model typically specifies an entity-defining
annotation that is used to identify entity classes. For Jakarta Persistence,
this is jakarta.persistence.Entity
. For Jakarta NoSQL, it is
jakarta.nosql.Entity
. A provider may even have no entity-defining
annotation and feature a programming model for entity classes where the
entity classes are unannotated.
Furthermore, an entity programming model must define an annotation which
identifies the field or property holding the unique identifier of an entity.
For Jakarta Persistence, it is jakarta.persistence.Id
or
jakarta.persistence.EmbeddedId
. For Jakarta NoSQL, it is
jakarta.nosql.Id
. Alternatively, an entity programming model might
allow the identifier field or property to be identified via some convention.
Every entity has a unique identifier.
An entity has an arbitrary number of persistent fields or properties.
Persistent field names
Each persistent field of an entity or embeddable class is assigned a name:
- when direct field access is used, the name of a persistent field is simply the name of the Java field, but
- when property-based access is used, the name of the field is derived from the accessor methods, according to JavaBeans conventions.
Within a given entity class or embeddable class, names assigned to persistent fields must be unique ignoring case.
Furthermore, within the context of a given entity, each persistent field of an embeddable class reachable by navigation from the entity class may be assigned a compound name. The compound name is obtained by concatenating the names assigned to each field traversed by navigation from the entity class to the persistent field of the embedded class, optionally joined by a delimiter.
- For parameters of a
Find
method, the delimiter is_
. - For path expressions within a query, the delimiter
is
.
. - For method names in Query by Method Name, the delimiter is
_
and it is optional. For example,findByAddress_ZipCode
orfindByAddressZipCode
are both legal. - For arguments to constructor methods of
Sort
, the delimiter is_
or.
. - For the
value
member of theOrderBy
orBy
annotation the delimiter is_
or.
.
A persistent field name used in a Query by Method Name must not contain a keyword reserved by Query by Method Name.
Persistent field types (basic types)
The following is a list of valid basic entity attribute types. These can be used as the types of repository method parameters for the respective entity attribute.
Category | Basic Types | Notes |
Primitives and primitive wrappers | boolean and Boolean
byte and Byte
char and Character
double and Double
float and Float
int and Integer
long and Long
short and Short |
|
Binary data | byte[] |
Not sortable. |
Enumerated types | enum types |
It is provider-specific whether sorting is based on
Enum.ordinal() or Enum.name() .
The Jakarta Persistence default of ordinal can be
overridden with the jakarta.persistence.Enumerated
annotation. |
Large numbers | BigDecimal
BigInteger |
|
Textual data | String |
|
Time and Dates | Instant
LocalDate
LocalDateTime
LocalTime |
|
Universally unique identifier | UUID |
All of the basic types are sortable except for byte[]
.
A Jakarta Data provider might allow additional entity attribute types.
Lifecycle methods
A lifecycle method makes changes to persistent data in the data store.
A lifecycle method must be annotated with a lifecycle annotation such as
Insert
, Update
, Save
, or Delete
. The
method must accept a single parameter, whose type is either:
- the class of the entity, or
List<E>
orE[]
whereE
is the class of the entities.
The annotated method must be declared void
, or, except in the
case of @Delete
, have a return type that is the same as the type
of its parameter.
Annotation | Description | Example |
Delete |
deletes entities | @Delete public void remove(person); |
Insert |
creates new entities | @Insert public List<Employee> add(List<Employee> newEmployees); |
Save |
update if exists, otherwise insert | @Save Product[] saveAll(Product... products) |
Update |
updates an existing entity | @Update public boolean modify(Product modifiedProduct); |
Refer to the API documentation for Insert
, Update
, Delete
,
and Save
for further information about these annotations.
JDQL query methods
The Query
annotation specifies that a method executes a query written
in Jakarta Data Query Language (JDQL) or Jakarta Persistence Query Language (JPQL).
A Jakarta Data provider is not required to support the complete JPQL language,
which targets relational data stores.
Each parameter of the annotated method must either:
- have exactly the same name (the parameter name in the Java source, or a name
assigned by
@Param
) and type as a named parameter of the query, - have exactly the same type and position within the parameter list of the method as a positional parameter of the query, or
- be of type
Limit
,Order
,PageRequest
, orSort
.
The Param
annotation associates a method parameter with a named parameter.
The Param
annotation is unnecessary when the method parameter name matches the
name of a named parameter and the application is compiled with the -parameters
compiler option making parameter names available at runtime.
// example using named parameters @Query("where age between :min and :max order by age") List<Person> peopleInAgeRange(int min, int max);
// example using an ordinal parameter @Query("where ssn = ?1 and deceased = false") Optional<Person> person(String ssn);
Refer to the API documentation for @Query
for further
information.
Query by Method Name
The Query by Method Name pattern translates the name of the
repository method into a query. The repository method must not include the
@Find
annotation, @Query
annotation, or any life cycle
annotations on the method, and it must not include any data access related
annotations on the method parameters. The method name must be composed of
one or more clauses that specify the query's action and optionally any
restrictions for matching and ordering of results. The following table lists
the method name prefixes available and shows an example query for each.
Prefix | Description | Example |
count |
counts the number of entities | countByAgeGreaterThanEqual(ageLimit) |
delete |
for delete operations | deleteByStatus("DISCONTINUED") |
exists |
for determining existence | existsByYearHiredAndWageLessThan(2022, 60000) |
find |
for find operations | findByHeightBetweenOrderByAge(minHeight, maxHeight) |
The method name must begin with an action clause that starts with a
prefix (count
, delete
, exists
, or find
) that
specifies the action of the query. The find
prefix can optionally be
followed by the keyword First
and 0 or more digits, which limit the
number of results retrieved. The remaining portion of the action clause is
ignored text that must not contain reserved keywords.
A restriction clause consisting of the By
keyword
followed by one or more conditions can optionally follow the action clause.
Multiple conditions must be delimited by the And
or Or
keyword.
Each condition consists of a case insensitive entity attribute name, optionally
followed by the IgnoreCase
keyword (for text properties), optionally
followed by the Not
keyword, optionally followed by a condition operator
keyword such as StartsWith
. The equality condition is implied when no
condition operator keyword is present. Most of the condition operations, such as
Like
or LessThan
, correspond to a single method parameter. The
exceptions to this rule are Between
, which corresponds to two method
parameters, and Null
, True
, and False
, which require
no method parameters.
A find
query can optionally end with an order,
consisting of the OrderBy
keyword and one or more pairings of case
insensitive entity attribute name followed by the Asc
or Desc
keyword, indicating ascending or descending sort. In the case of a single entity
attribute, the paired keyword can be omitted, in which case ascending sort is
implied.
Key-value and Wide-Column databases raise UnsupportedOperationException
for queries on attributes other than the identifier/key.
Reserved keywords for Query by Method Name
Keyword | Applies to | Description | Example | Unavailable In |
And |
conditions | Requires both conditions to be satisfied in order to match an entity. | findByNameLikeAndPriceLessThanEqual(namePattern, maxPrice) |
Key-value Wide-Column |
Between |
sortable basic types | Requires that the entity's attribute value be within the range specified by two parameters, inclusive of the parameters. The minimum is listed first, then the maximum. | findByAgeBetween(minAge, maxAge) |
Key-value Wide-Column |
Contains |
strings | Requires that a substring of the entity's attribute value matches the parameter value, which can be a pattern. | findByNameContains(middleName) |
Key-value Wide-Column Document Graph |
EndsWith |
strings | Requires that the characters at the end of the entity's attribute value match the parameter value, which can be a pattern. | findByNameEndsWith(surname) |
Key-value Wide-Column Document Graph |
False |
boolean | Requires that the entity's attribute value has a boolean value of false. | findByCanceledFalse() |
Key-value Wide-Column |
GreaterThan |
sortable basic types | Requires that the entity's attribute value be larger than the parameter value. | findByStartTimeGreaterThan(startedAfter) |
Key-value Wide-Column |
GreaterThanEqual |
sortable basic types | Requires that the entity's attribute value be at least as big as the parameter value. | findByAgeGreaterThanEqual(minimumAge) |
Key-value Wide-Column |
IgnoreCase |
strings | Requires case insensitive comparison. For query conditions
as well as ordering, the IgnoreCase keyword can be
specified immediately following the entity property name. |
countByStatusIgnoreCaseNotLike("%Delivered%")
findByZipcodeOrderByStreetIgnoreCaseAscHouseNumAsc(55904) |
Key-value Wide-Column Document Graph |
In |
sortable basic types | Requires that the entity attribute value belong to the Set that is
the parameter value. |
findByMonthIn(Set.of(Month.MAY, Month.JUNE)) |
Key-value Wide-Column Document Graph |
LessThan |
sortable basic types | Requires that the entity's attribute value be less than the parameter value. | findByStartTimeLessThan(startedBefore) |
Key-value Wide-Column |
LessThanEqual |
sortable basic types | Requires that the entity's attribute value be at least as small as the parameter value. | findByAgeLessThanEqual(maximumAge) |
Key-value Wide-Column |
Like |
strings | Requires that the entity's attribute value match the parameter value, which can be a pattern. | findByNameLike(namePattern) |
Key-value Wide-Column Document Graph |
Not |
condition | Negates a condition. | deleteByNameNotLike(namePattern)
findByStatusNot("RUNNING") |
Key-value Wide-Column |
Null |
nullable types | Requires that the entity's attribute has a null value. | findByEndTimeNull()
findByAgeNotNull() |
Key-value Wide-Column Document Graph |
Or |
conditions | Requires at least one of the two conditions to be satisfied in order to match an entity. | findByPriceLessThanEqualOrDiscountGreaterThanEqual(maxPrice, minDiscount) |
Key-value Wide-Column |
StartsWith |
strings | Requires that the characters at the beginning of the entity's attribute value match the parameter value, which can be a pattern. | findByNameStartsWith(firstTwoLetters) |
Key-value Wide-Column Document Graph |
True |
boolean | Requires that the entity's attribute value has a boolean value of true. | findByAvailableTrue() |
Key-value Wide-Column |
Keyword | Applies to | Description | Example | Unavailable In |
First |
find...By | Limits the amount of results that can be returned by the query
to the number that is specified after First ,
or absent that to a single result. |
findFirst25ByYearHiredOrderBySalaryDesc(int yearHired)
findFirstByYearHiredOrderBySalaryDesc(int yearHired) |
Key-value Wide-Column Document Graph |
Keyword | Description | Example |
Asc |
Specifies ascending sort order for findBy queries |
findByAgeOrderByFirstNameAsc(age) |
Desc |
Specifies descending sort order for findBy queries |
findByAuthorLastNameOrderByYearPublishedDesc(surname) |
OrderBy |
Sorts results of a findBy query according to one or more entity attributes.
Multiple attributes are delimited by Asc and Desc ,
which indicate ascending and descending sort direction.
Precedence in sorting is determined by the order in which attributes are listed. |
findByStatusOrderByYearHiredDescLastNameAsc(empStatus) |
Key-value and Wide-Column databases raise UnsupportedOperationException
if an order clause is present.
Reserved for future use
The specification does not define behavior for the following keywords, but reserves them as keywords that must not be used as entity attribute names when using Query by Method Name. This gives the specification the flexibility to add them in future releases without introducing breaking changes to applications.
Reserved for query conditions: AbsoluteValue
, CharCount
,
ElementCount
, Empty
,
Rounded
, RoundedDown
, RoundedUp
, Trimmed
,
WithDay
, WithHour
, WithMinute
, WithMonth
,
WithQuarter
, WithSecond
, WithWeek
, WithYear
.
Reserved for find
and count
: Distinct
.
Reserved for updates: Add
, Divide
, Multiply
, Set
, Subtract
.
Wildcard characters
Wildcard characters for patterns are determined by the data access provider.
For Jakarta Persistence providers, _
matches any one character
and %
matches 0 or more characters.
Logical operator precedence
For relational databases, the logical operator And
is evaluated on conditions before Or
when both are specified
on the same method. Precedence for other database types is limited to
the capabilities of the database.
Return types for Query by Method Name
The following is a table of valid return types. The Method column shows name patterns for Query by Method Name.
Method | Return Types | Notes |
count |
long |
|
delete |
void ,
long ,
int |
|
exists |
boolean |
For determining existence |
find |
E ,
Optional<E> |
For queries returning a single item (or none) |
find |
E[] ,
List<E> |
For queries where it is possible to return more than 1 item |
find |
Stream<E> |
The caller must call close
for every stream returned by the repository method |
find accepting PageRequest |
Page<E> , CursoredPage<E> |
For use with pagination |
Parameter-based automatic query methods
The Find
annotation indicates that the repository method is
a parameter-based automatic query method. In this case, the method name
does not determine the semantics of the method, and the query conditions
are determined by the method parameters.
Each parameter of the annotated method must either:
- have exactly the same type and name (the parameter name in the Java
source, or a name assigned by
@By
) as a persistent field or property of the entity class, or - be of type
Limit
,Sort
,Order
, orPageRequest
.
A parameter may be annotated with the By
annotation to specify
the name of the entity attribute that the argument is to be compared with.
If the By
annotation is missing, the method parameter name must
match the name of an entity attribute and the repository must be compiled
with the -parameters
compiler option so that parameter names are
available at runtime.
Each parameter determines a query condition, and each such condition is an equality condition. All conditions must match for a record to satisfy the query.
@Find @OrderBy("lastName") @OrderBy("firstName") List<Person> peopleByAgeAndNationality(int age, Country nationality);
@Find Optional<Person> person(String ssn);
The _
character may be used in a method parameter name to
reference an embedded attribute.
@Find @OrderBy("address.zip") Stream<Person> peopleInCity(String address_city);
The following examples illustrate the difference between Query By Method Name and parameter-based automatic query methods. Both methods accept the same parameters and have the same behavior.
// Query by Method Name Vehicle[] findByMakeAndModelAndYear(String makerName, String model, int year, Sort<?>... sorts); // parameter-based conditions @Find Vehicle[] searchFor(String make, String model, int year, Sort<?>... sorts);
For further information, refer to the API documentation
for @Find
.
Special parameters
A repository method annotated @Query
, @Find
or
following the Query by Method Name pattern may have special
parameters of type Limit
, Order
, Sort
, or
PageRequest
if the method return type indicates that the method may
return multiple entities. Special parameters occur after parameters related
to query conditions and JDQL query parameters, and enable capabilities such
as pagination, limits, and sorting.
Limits
The number of results returned by a single invocation of a repository
find method may be limited by adding a parameter of type Limit
.
The results may even be limited to a positioned range. For example,
@Query("WHERE (fullPrice - salePrice) / fullPrice >= ?1 ORDER BY salePrice DESC, id ASC") Product[] highlyDiscounted(float minPercentOff, Limit limit); ... first50 = products.highlyDiscounted(0.30, Limit.of(50)); ... second50 = products.highlyDiscounted(0.30, Limit.range(51, 100));
Pagination
A repository find method with a parameter of type PageRequest
allows its results to be split and retrieved in pages. For example,
Product[] findByNameLikeOrderByAmountSoldDescIdAsc( String pattern, PageRequest pageRequest); ... page1 = products.findByNameLikeOrderByAmountSoldDescIdAsc( "%phone%", PageRequest.ofSize(20));
When using pagination, always ensure that the ordering is consistent across invocations. One way to achieve this is to include the unique identifier in the sort criteria.
Sorting
When a page is requested with a PageRequest
, dynamic sorting
criteria may be supplied by passing instances of Sort
or Order
.
For example,
Product[] findByNameLike(String pattern, PageRequest pageRequest, Order<Product> order); ... PageRequest page1Request = PageRequest.ofSize(25); page1 = products.findByNameLikeAndPriceBetween( namePattern, minPrice, maxPrice, page1Request, Order.by(Sort.desc("price"), Sort.asc("id"));
To supply sort criteria dynamically without using pagination, an
instance of Order
may be populated with one or more instances
of Sort
and passed to the repository find method. For example,
Product[] findByNameLike(String pattern, Limit max, Order<Product> sortBy); ... found = products.findByNameLike(namePattern, Limit.of(25), Order.by(Sort.desc("price"), Sort.desc("amountSold"), Sort.asc("id")));
Generic, untyped Sort
criteria can be supplied directly to a
repository method with a variable arguments Sort<?>...
parameter.
For example,
Product[] findByNameLike(String pattern, Limit max, Sort<?>...
sortBy);
...
found = products.findByNameLike(namePattern, Limit.of(25),
Sort.desc("price"),
Sort.desc("amountSold"),
Sort.asc("name"));
Repository default methods
A repository interface may declare any number of default
methods
with user-written implementations.
Resource accessor methods
In advanced scenarios, the application program might make direct use of
some underlying resource acquired by the Jakarta Data provider, such as a
javax.sql.DataSource
, java.sql.Connection
, or even an
jakarta.persistence.EntityManager
.
To expose access to an instance of such a resource, the repository interface may declare an accessor method, a method with no parameters whose return type is the type of the resource, for example, one of the types listed above. When this method is called, the Jakarta Data provider supplies an instance of the requested type of resource.
For example,
@Repository public interface Cars extends BasicRepository<Car, Long> { ... EntityManager getEntityManager(); default Car[] advancedSearch(SearchOptions filter) { EntityManager em = getEntityManager(); ... use entity manager return results; } }
If the resource type inherits from AutoCloseable
and the
accessor method is called from within an invocation of a default method
of the repository, the Jakarta Data provider automatically closes the
resource after the invocation of the default method ends. On the other
hand, if the accessor method is called from outside the scope of a
default method of the repository, it is not automatically closed, and
the application programmer is responsible for closing the resource
instance.
Precedence of repository methods
The following order, with the lower number having higher precedence, is used to interpret the meaning of repository methods.
- If the method is a Java
default
method, then the provided implementation is used. - If a method has a resource accessor method return type recognized by the Jakarta Data provider, then the method is implemented as a resource accessor method.
- If a method is annotated with a query annotation
recognized by the Jakarta Data provider, such as
Query
, then the method is implemented to execute the query specified by the query annotation. - If the method is annotated with an automatic query annotation,
such as
Find
, or with a lifecycle annotation declaring the type of operation, for example, withInsert
,Update
,Save
, orDelete
, and the provider recognizes the annotation, then the annotation determines how the method is implemented. - If a method is named according to the conventions of Query by Method Name, then the implementation follows the Query by Method Name pattern.
A repository method which does not fit any of the listed patterns
and is not handled as a vendor-specific extension must either cause
an error at build time or raise UnsupportedOperationException
at runtime.
Identifying the type of entity
Most repository methods perform operations related to a type of entity.
In some cases, the entity type is explicit within the signature of the
repository method, and in other cases, such as countBy...
and
existsBy...
the entity type cannot be determined from the method
signature and a primary entity type must be defined for the repository.
Methods where the entity type is explicitly specified
In the following cases, the entity type is determined by the signature of the repository method.
- For repository methods annotated with
Insert
,Update
,Save
, orDelete
where the method parameter type is a type, an array of a type, or is parameterized with a type annotated as an entity, such asMyEntity
,MyEntity[]
, orList<MyEntity>
, the entity type is determined by the method parameter type. - For
find
anddelete
methods where the return type is a type, an array of a type, or is parameterized with a type annotated as an entity, such asMyEntity
,MyEntity[]
, orPage<MyEntity>
, the entity type is determined by the method return type.
Identifying a primary entity type:
The following precedence, from highest to lowest, is used to determine a primary entity type for a repository.
- The primary entity type for a repository interface may be specified
explicitly by having the repository interface inherit a superinterface
like
CrudRepository
, where the primary entity type is the argument to the first type parameter of the superinterface. For example,Product
, in,@Repository public interface Products extends CrudRepository<Product, Long> { // applies to the primary entity type: Product long countByPriceLessThan(float max); }
- Otherwise, if the repository declares lifecycle methods—that is,
has methods annotated with a lifecycle annotation like
Insert
,Update
,Save
, orDelete
, where the method parameter type is a type, an array of a type, or is parameterized with a type annotated as an entity—and all of these methods share the same entity type, then the primary entity type for the repository is that entity type. For example,@Repository public interface Products { @Insert List<Product> add(List<Product> p); @Update Product modify(Product p); @Save Product[] save(Product... p); // applies to the primary entity type: Product boolean existsByName(String name); }
Jakarta Validation
When a Jakarta Validation provider is present, constraints that are defined on repository method parameters and return values are validated according to the section, "Method and constructor validation", of the Jakarta Validation specification.
The jakarta.validation.Valid
annotation opts in to cascading validation,
causing constraints within the objects that are supplied as parameters
or returned as results to also be validated.
Repository methods raise jakarta.validation.ConstraintViolationException
if validation fails.
The following is an example of method validation, where the
parameter to findByEmailIn
must not be the empty set,
and cascading validation, where the Email
and NotNull
constraints
on the entity that is supplied to save
are validated,
import jakarta.validation.Valid; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; ... @Repository public interface AddressBook extends DataRepository<Contact, Long> { List<Contact> findByEmailIn(@NotEmpty Set<String> emails); @Save void save(@Valid Contact c); } @Entity public class Contact { @Email @NotNull public String email; @Id public long id; ... }
Jakarta Interceptors
A repository interface or method of a repository interface may be annotated with an
interceptor binding annotation. In the Jakarta EE environment, or in any other environment
where Jakarta Interceptors is available and integrated with Jakarta CDI, the repository
implementation is instantiated by the CDI bean container, and the interceptor binding type
is declared @Inherited
, the interceptor binding annotation is inherited by the
repository implementation, and the interceptors bound to the annotation are applied
automatically by the implementation of Jakarta Interceptors.
Jakarta Transactions
When Jakarta Transactions is available, repository methods can participate in global transactions. If a global transaction is active on the thread of execution in which a repository method is called, and the data source backing the repository is capable of transaction enlistment, then the repository operation is performed within the context of the global transaction.
The repository operation must not not commit or roll back a transaction which was
already associated with the thread in which the repository operation was called, but it
might cause the transaction to be marked for rollback if the repository operation fails,
that is, it may set the transaction status to Status.STATUS_MARKED_ROLLBACK
.
A repository interface or method of a repository interface may be marked with the
annotation jakarta.transaction.Transactional
. When a repository operation marked
@Transactional
is called in an environment where both Jakarta Transactions and
Jakarta CDI are available, the semantics of this annotation are observed during execution
of the repository operation.
-
Packages
PackageExported To ModulesOpened To ModulesDescriptionAll ModulesNoneJakarta Data provides an API that simplifies data access.All ModulesNoneCommon data access exceptions.All ModulesNoneA static metamodel for entities that are used in Jakarta Data repositories.All ModulesNoneAll ModulesNoneSplits query results into pages.All ModulesNoneAll ModulesAll ModulesA repository is an interface annotated withRepository
that defines operations on entities.All ModulesNone