Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite section on Portability for Relational Databases #469

Merged
merged 2 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions spec/src/main/asciidoc/jakarta-ee.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,14 @@ When a repository method is annotated with an interceptor binding annotation, th

=== Jakarta Persistence

When integrating Jakarta Data with Jakarta Persistence, developers can leverage the JPA annotations to define the mapping of entities in repositories. Entities in Jakarta Persistence are typically annotated with `jakarta.persistence.Entity` to indicate their persistence capability.
When integrating Jakarta Data with Jakarta Persistence, a developer uses the annotations defined in `jakarta.persistence` to specify the object/relational mapping metadata for entity types stored in a relational database.

A Jakarta Data provider that supports Jakarta Persistence allows you to define repositories for classes marked with the `jakarta.persistence.Entity` annotation.
According to the Jakarta Persistence specification, every entity class should be annotated `jakarta.persistence.Entity`. Jakarta Data places an additional interpretation on this annotation, treating it as an entity-defining annotation.

By supporting Jakarta Persistence annotations, Jakarta Data providers enable Java developers to utilize familiar and standardized mapping techniques when defining entities in repositories, ensuring compatibility and interoperability with the respective technologies.
Thus, a Jakarta Data provider which supports Jakarta Persistence is able to supply an implementation of any repository whose associated entity classes are marked with the `jakarta.persistence.Entity` annotation. Typically, such an implementation simply delegates operations declared by the repository interface to the Jakarta Persistence `EntityManager`. Management of persistence contexts and integration with Jakarta Transactions remains the responsibility of the Jakarta Persistence provider.

==== Persistence Context
By supporting Jakarta Persistence, a Jakarta Data provider enables Java developers to utilize familiar and standardized mapping techniques when defining entities associated with Jakarta Data repositories, ensuring compatibility and interoperability with the respective technologies.

Repository operations must behave as though backed by a stateless Entity Manager in that persistence context is not preserved across the end of repository methods. All entities that are returned by repository methods must be in a detached state such that modifications to these entities are not persisted to the database unless the application explicitly invokes a `Save` or `Update` life cycle method for the entity.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize the stateless EntityManager didn't make it into Jakarta Persistence 3.2, but it would be nice to be able to standardize the behavior in anticipation of it. I think it should be possible to simulate the behavior with what is currently in the Jakarta Persistence API unless I'm missing something. Although I suppose it will be somewhat inefficient to do so. I don't really like leaving it so unclear in the Jakarta Data spec, which leaves the user wondering what behavior they will end up with, or maybe assuming a behavior that is not the right one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK so as I've argued elsewhere the implementations don't in principle need to wait for permission from the JPA spec to offer stateless sessions. So if you want me put back in something about this approach, that's totally fine, but I want it to be clear that you can also have a repository backed by a regular stateful session, and the previous language sounded like it was disallowing that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @otaviojava already merged this one on the basis of my review of the first commit. Apparently git doesn't reset the review status when more commits are added. We will need to ensure this discussion doesn't get lost because the change has been applied already.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this is easier to specify if I can talk about it in terms of @Insert vs @Persist if you get my drift.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @otaviojava already merged this one on the basis of my review of the first commit. Apparently git doesn't reset the review status when more commits are added. We will need to ensure this discussion doesn't get lost because the change has been applied already.

Don't worry Nathan I can write this up tonight if we agree on the basic idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@njr-11 So how about something like this:

A Jakarta Data provider which supports Jakarta Persistence entities bearing the annotation jakarta.persistence.Entity may support either or both of the following repository styles:

  • A repository might be backed by a Jakarta Persistence EntityManager with a stateful persistence context. The lifecycle operations of the repository are annotated with the Jakarta Persistence-specific annotations @Persist, @Merge, and friends, and follow the semantics of the corresponding standard operations of jakarta.persistence.EntityManager. In particular, the repository observes the semantics of the Jakarta Persistence CascadeType.
  • Alternatively, a repository might by "stateless", in the sense that it does not maintain a persistence context which outlives the invocation of a single repository method. The lifecycle operations of this kind of repository are annotated @Insert, @Delete, or @Update, and adhere to the usual semantics of these annotations. In particular, these operations never cascade to related entities.

That's just a first cut, of course.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I did not see this discussion.


=== Jakarta NoSQL

Expand Down
42 changes: 33 additions & 9 deletions spec/src/main/asciidoc/portability.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,47 @@ The portability that is offered by Jakarta Data pertains to usage of the Jakarta

=== Portability for Relational Databases

All functionality defined by Jakarta Data must be supported when using relational databases.
Jakarta Data is intended to be compatible with two very different approaches to relational data access:

==== Jakarta Persistence Annotations
- In the approach typified by Jakarta Persistence, entities are _managed objects_ associated with a _persistence context_, and have a well-defined _persistence lifecycle_. Under this approach, an entity instance maintains its association with the Jakarta Data provider between repository method calls.

A Jakarta Data provider backed by Jakarta Persistence must allow the use of `jakarta.persistence.Entity` as an entity-defining annotation.
- In the _persistence context free_ approach, entity instances are unmanaged objects, and their association with the Jakarta Data provider never outlasts a single call to a lifecycle method or query method of a repository.

==== Built-In Repositories
The two approaches feature very different patterns of interaction with the repository, and it is not a goal of Jakarta Data to abstract away the differences.

Jakarta Data's built-in repositories, such as `BasicRepository` and `CrudRepository`, are designed to offer consistent and well-defined methods compatible with relational databases. Developers can rely on these repositories to perform common data access tasks.
Regardless of the approach, a Jakarta Data provider backed by access to relational data must fully support Jakarta Data query methods, including pagination, ordering, and limiting, subject to the caveats specified below.

==== Query Methods
==== Jakarta Persistence

Jakarta Data's support for query methods, including pagination, ordering, and limiting, is designed to work seamlessly with relational databases.
In Jakarta Persistence, an instance of `EntityManager` reifies access to a given persistence context.
Jakarta Persistence does not currently support the persistence context free approach.

All limitations of Jakarta Persistence, the respective Jakarta Persistence provider, JPQL, SQL, and the database apply when using entities that are annotated with `jakarta.persistence.Entity`. Repository methods must correspond to operations that are valid via `JPQL` and `SQL` queries. For example, although one can write a repository method that asks for sorting by a collection attribute or attempts to perform a Like operation on a numeric type rather than a String, there is no expectation for a Jakarta Data provider to support doing so because Jakarta Persistence, JPQL, and SQL do not offer the ability.
A Jakarta Data provider backed by Jakarta Persistence must:

By aligning Jakarta Data closely with relational databases, developers can expect high portability and compatibility. This approach ensures that Jakarta Data remains a powerful tool for simplifying data access, irrespective of the specific relational database used.
- allow the use of `jakarta.persistence.Entity` as an entity-defining annotation,
- along with resource accessor methods of type `jakarta.persistence.EntityManager`.

A Jakarta Data provider backed by Jakarta Persistence should define a query annotation accepting JPQL as the query language, along with an annotation accepting native SQL as the query language.

[CAUTION]
====
This release of Jakarta Data does not standardize lifecycle annotations or query annotations for use with Jakarta Data providers backed by Jakarta Persistence.
====

The Jakarta Persistence specification, the respective Jakarta Persistence provider, JPQL, SQL, and the database all set limitations on what is possible for a repository implementation backed by Jakarta Persistence. All such limitations apply when the entities associated with a Jakarta Data repository are declared using the annotation `jakarta.persistence.Entity`. In particular, repository query methods must correspond to operations which are legal JPQL and SQL queries.

For example, although one can write a repository method that asks for sorting by a collection attribute or attempts to perform a Like operation on a numeric type rather than a String, there is no expectation that a Jakarta Data provider backed by Jakarta Persistence should be able to supply an implementation of such a repository.

==== Other Relational Data Access Technologies

A Jakarta Data provider for relational data does not need to be based on Jakarta Persistence, and is not required to feature persistence contexts.

A Jakarta Data provider based on persistence context free access to relational data must support the built-in lifecycle annotations `@Insert`, `@Update`, and `@Delete`, along with the built-in repository types `BasicRepository` and `CrudRepository`.

If the provider is backed by JDBC, it should support resource accessor methods of type `java.sql.Connection`.

As above, the SQL dialect and the database set limits on what operations are implementable.
The Jakarta Data provider is not required to supply an implementation of a repository which declares query methods mapping to operations which are not supported by the database itself.

=== Portability for NoSQL Databases

Expand Down