Is JPA PersistenceContextType managed by container? - jpa

JPA defines PersistenceContextType, but it is not referenced anywhere in JPA api.
public enum PersistenceContextType {
TRANSACTION,
EXTENDED
}
Is persistence context (whether transaction or extended) is managed by container(e.g. JEE), not JPA itself?

but it is not referenced anywhere in JPA api
It is referenced by the declarative API - the type property of the #PersistenceContext annotation. It wouldn't make sense for it to be referenced by any programmatic API, because application-managed EntityManagers are always of the EXTENDED type, as the TRANSACTION type wouldn't make much sense.
Is persistence context (whether transaction or extended) is managed by container(e.g. JEE), not JPA itself?
Not entirely sure I understand the question but, as per the spec (Section 7.6):
When a container-managed entity manager is used, the lifecycle of the persistence context is always
managed automatically, transparently to the application, and the persistence context is propagated with
the JTA transaction.
Note that a container-managed, EXTENDED persistence context can only be requested (using #PersistenceContext(type = EXTENDED)) in stateful beans, which are barely used nowadays.
(see that section, and the sections that follow, for more details on how transaction and extended scopes work)
EDIT:
As for why #PersistenceContext and PersistenceContextType is part of the JPA API, the answer is: why shouldn't it? The JPA API is primarily a JEE API and everything persistence-related that your app may want to use as an API goes in there. In JEE context, Hibernate, EclipseLink etc. are technically not implementations of the JPA API; rather, they're service providers for the PersistenceProvider service. It's a very subtle difference; however, even though they obviously do 99% percent of the work, from the application's point of view, it is still the container that provides (exposes) the JPA API.
(Another point of view could be that JPA providers implement the programmatic part of the API while containers implement the declarative part, but that's a purely academic discussion).

Related

How to use Autofac to inject the same instance of DbContext for processing an HTTP request without causing concurrency issues?

I'm working on an ASP.net Web API application with Autofac and Entity Framework.
I've been breaking apart different my service classes into smaller classes in order to make my code more testable and to make my code more SOLID.
I'm using Autofac to inject Entity Framework DbContext into my various helper classes. This becomes problematic because if I use entities queried from DbContext in two different helper classes, I get an error when Entity Framework tries to produce a query.
The error says that Entity Framework cannot produce a query with entities from two different instances of DbContext.
Clearly, the solution is that I need to configure Autofac so that the same instance of DbContext is injected into each of the helper classes, but I'm afraid that if I try to do this, I may get concurrency issues when this application gets deployed to a production environment and many people use it at once.
How do I configure Autofac so that when a request hits my application, my API helper classes all get the same instance of DbContext, but I don't have concurrency issues across multiple requests?
An alternative to the action filter recommended by the Autofac documentation (https://autofaccn.readthedocs.io/en/latest/faq/per-request-scope.html#no-per-request-filter-dependencies-in-web-api) see: "No Per-Request Filter Dependencies in Web API" and manually going to the DependencyResolver for others:
You could have a look at the Medhime DbContextScope unit of work provider. (https://www.nuget.org/packages/EntityFramework.DbContextScope/) compiled for both EF6 and EF Core.
The injected dependencies for your classes becomes a DbContextScopeFactory for the top level, and an AmbientDbContextLocator for your services. These don't "break" with Web API's limitation on the request lifetime scope. The ContextScopeFactory would be initialized once and supply the DbContext, while the locators will be fed that single instance.
It may be worth having a look at if managing context references across services and an API action prove clunky.

EclipseLink (JPA) table-based multitenancy with JTA, how?

Our application project is an OSGI bundle using JPA with EclipseLink and JTA, and needs single-table multi-tenancy, where tenant ID comes from a REST request. From what I've read and tried, it almost seems that is impossible:
Since tenant ID changes depending on the request, each request with a new tenant ID needs to manually create a new PersistenceContext (EntityManager) with the appropriate property.
But persistence contexts can't be manually created when using JTA (#PersistenceUnit does not get injected and Persistence.createEntityManagerFactory does not work), according to http://tomee.apache.org/jpa-concepts.html.
Am I missing something? Or is this literally impossible to do?
You can set multitenant/discriminator properties in the entity manager for a request. But it is not safe for multi-threading and lazy initialization.
I tried our CMobileCom JPA that supports single-table multitenancy. For each tenant, a new EntityManager should be used. That is, an EntityManager should not be shared to access data for multiple tenants. This is also true for EclipseLink.
Disclaimer: I am a developer of CMobileCom JPA, a light weight JPA implementation for Java and Android.

JPA Entity in JSF vs tight coupling

I have a follow up question to the answer provided in below post
JPA Entity as JSF Bean?
I know this is the practice used in JSF applications but, I fail to understand how the approach provided in that post eliminates tight coupling? Could someone please answer?
The view is not really decoupled from it's underlying model as it's purpose it to display the internals of it's model.
However it makes a difference what this view model is and how it is attached to the view, and there are some gains in not backing the view by a persistent entity directly.
The backing bean often has to perform service calls or at least CRUD operations. Neither should be a concern of a JPA entity. The controller might also be useful for validation, access restrictions, caching etc.
A JPA entity usually does not control it's own lifecycle. Making it a backing bean would probably require the entity to control it's own transactions, at least to handle CRUD operations. This could work with an ActiveRecord implementation, but IMHO JPA entities do not lend themselves to the AR pattern too well.
In Java EE aplications, the DTO pattern is often used to decouple the persistence from the view, other external systems, or even from all layers of the application above the DAL. Entities are mapped to DTOs with more specific purposes, e.g. presenting a relevant selection of attributes from different entities to the frontend.
EDIT: If I have understood you issue correctly - you have an application where the getters of backing beans perform DB operations and cause your application to be slow.
This is in fact a bad practice. The JSF lifecycle causes these getters to be called multiple times, each of the calls resulting in an unnecessary DB call.
The common practice is to fetch the complete data from DB after the backing bean was constructed and before data is displayed initially (effectively caching the data for the lifetime of the backing bean). The data should be refetched from DB only if the user explicitly refreshes it.
Please see this post for further explanation.

Is there a REST-based JPA provider?

A common requirement is to access a JPA DataSource via REST. I want the opposite, i.e. a JPA provider that works by sending HTTP requests to a RESTful persistence service. The benefit of this is that any application written against the JPA API could easily switch between a traditional JPA provider (e.g. Hibernate) and the REST-based JPA provider, with no code changes required.
So my question is whether there is an existing REST-based JPA provider, and if not, would such a thing even be feasible?
Datanucleaus has a JPA implementation over a RESTful json API. However, your REST API must adhere to their conventions: http://www.datanucleus.org/products/accessplatform_3_0/json/support.html
Their S3 and GoogleStorage extend the json API.
EDIT: Put link to wrong product in my original answer.
First of all, JPA is really designed for relational databases...
Second, there is no standard for RESTful persistence so a JPA-REST provider would be specific to that REST persistence application.
You could implement something using EclipseLink-EIS. You'd just have to create the JCA_RestAdapter implementation.
If you mean one of the NoSQL databases when you say "RESTful persistence service" then maybe. Some of these NoSQL DBs provide a REST based interface and some JPA providers are starting to support NoSQL DBs. See http://wiki.eclipse.org/EclipseLink/FAQ/NoSQL.
Honestly you'd be better off just implementing the DAO pattern and abstracting your CRUD(L) operations. This is exactly what DAOs are for.
There are several alternatives out there. For example, take a look at "JEST":
https://www.ibm.com/developerworks/mydeveloperworks/blogs/pinaki/entry/rest_and_jpa_working_together71?lang=en
REST is not an API (Application Programming Interface). It is an
architectural style that prescribes not to have an API to access the
facilities of a service.
...
On the opposite end of the stateless spectrum lies the principle of
JEE Application Servers -- where the server maintains state of
everything and there exists one (or multiple) API for everything. Such
server-centric, stateful, API-oriented principles of JEE led to
several roadblocks.
...
I found REST principles concise and elegant. I also find Java
Persistence API (JPA) providers have done a great job in standardizing
and rationalizing the classic object-relational impedance mismatch.
JPA is often misconstrued as a mere replacement of JDBC -- but it is
much more than JDBC and even more than Object-Relational Mapping
(ORM). JPA is be a robust way to view and update relational data as an
object graph. Also core JPA notions such as detached transaction or
customizable closure or persistent identity are seemed to neatly
aligned with REST principles.
Further links:
http://openjpa.apache.org/jest.html
http://www.ibm.com/developerworks/java/library/j-jest/index.html?ca=drs-

JavaEE changing DB schema runtime for SaaS application

i am developing a SaaS application by using JavaEE technologies (JPA, EJB, ..)
for multitenancy, i chose 'Shared Database, Separate Schemas' approach and designed the DB (PostgreSQL) like that
basically what i need to do is changing the default schema for user sessions in the application so that users can get their own data from the right schema
my business logic is implemented with EJB (Container-managed) and the app server is glassfishv3
so in my EJBs i am just injecting the EntityManager like this
#PersistenceContext(unitName="DBNAME")
private EntityManager em;
and leaving the transaction management to the glassfish
i tried to write #PostConstruct callbacks for Stateless EJBs injecting DataSource
but getClientInfo() returns null somehow so i can not even see the default schema. The reason why i injected DataSource was because i thought i have to do some low-level stuff to specify the schema.
i know if i manage the transactions in the application instead of leaving them to the app server, i can change the EntityManager values through EMF easily but i wanna keep the Container-managed infrastructure and just change some values at runtime
is there any way to do this with SessionContext or anything else ?
what is the best way of overcoming this issue ?
thanks in advance
#PostConstruct is by definition the wrong way, because it is only a hint to the bean that it has been constructed and its dependencies have been injected. The bean is now in the pool of EJBs waiting for the first service call. Then it will be connected to the client info of that call. After that call the client info is disconnected again.
I think any kind of standard injection and standard container managed persistence stuff will not work in your case because injection is done exactly once (at EJB creation time) but your case would require injection for each service call/transaction _AND your injection would depend on input data - the client request containing the tenant id.
Also: I hope, you have only up to 6 (or so) tenants due to the maintenance and performance burden of that approach. I have never seen this approach working in the wild.