Is it possible to disable caching with EntityManager in some jboss config?
I'll explain. I have some final "ear" of our product that is using EntityManager through hibernate (something like this, i an newbie to this) and I need to test some behaviour. The easy way for me is to change(remove, create) state of entities direct in the database. But after i did this, the application remain to find old values for some time. I've read about some jboss cache, that is used for entity-manager.
So, for testing, i want to disable EntityManager cache, but it can not be disabled on application-level, only on jboss-level.
In brief: i need application always to reload actual entity state, because it can be edited in database with come other application. And its impossible to disable caching on application-level(hibernate.xml and other)
PS: jboss 4.2.3, ejb3, hibernate3
The cache you are referring to is probably the PersistenceContext. It cannot be disabled. You can only tweak it's scope. In a Java EE environment, the scope of the persistence context is the transaction per default. So if you need for some changes to take effect immediately, you can extract these changes (including fetching the entities in question) into a separate method and annotate it to require a new transaction:
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
Once the method returns, all changes are committed.
You could also use bean managed transactions, so you can control the commit yourself. For this, annotate your bean with #TransactionManagement( TransactionManagementType.BEAN ) and use UserTransaction:
#Resource
private UserTransaction tx;
...
tx.begin();
//do stuff
tx.commit();
Related
I am analysing a "classic" Hibernate error :
org.hibernate.LazyInitializationException : could not initialize proxy – no Session.
I am wondering how it could happen whereas the Spring Open In View mode is enabled?
If you have any documentation or knowledge on a possible reason, please share.
Thanks
Here are some feebacks on my context, and an example of what could cause LazyInitializationException event if Spring Open In View is enabled.
Context
My application is a REST API server developed with Spring Boot 2.5.3.
Spring Open In View is kept enabled by default.
A lot of Services are annotated with #Transactional methods.
Spring-data is used, and Entitymanager too, to create some native queries.
The error
One REST API request, that generates a lot requests to the database (both selections and insertions), fails with LazyInitializationException.
Debugging
By setting a breakpoint when LazyInitializationException is thrown, I discovered that the exception is thrown in org.hibernate.proxy.AbstractLazyInitializer#initialize, because the session is null. Then I discovered that the session is set to null, when the method EntityManager.clear is called. For any reason I don't know, this method was explicitely called in the code.
Fixing
So I just removed the call to EntityManager.clear, and the request works. I'm still wondering why previous developers wanted to clear the EntityManager, probably because they were confused with the transaction management.
Conclusion
Even in Spring Open In View is enabled, and as a result, event if a Hibernate Session is opened, calling EntityManager.clear unset the session to the entities loaded before. Then trying to access a Lazy Loaded field on those entities throws LazyInitializationException.
I hope this will help someone.
Here is the documentation from the latest hibernate version.
As you can see
Indicates an attempt to access not-yet-fetched data outside of a
session context. For example, when an uninitialized proxy or
collection is accessed after the session was closed.
Most probably somewhere you read some entity and then outside of a transaction you try to read some collection which was by default lazy loaded. So then another request needs to be done to database, but since you are out of transaction you receive this exception.
This usually occurs in case you load an entity without the annotation #Transactional or some other configuration to load it inside a transaction and then you give this to your controller to be returned to the user. Then the controller will use jackson or some other library to convert the entity object into a json and will try to read any field. At this point trying to read any lazy loaded collections from the entity, will result in this exception since the read will be outside of a transaction.
what is the difference between TransactionManagementType.CONTAINER and TransactionManagementType.BEAN
as Im using TransactionManagementType.CONTAINER in all of my EJBs and when ever the multiple instances of database is used, It throws an error which gets resolved if i change it to TransactionManagementType.BEAN
I want to know what are the advantages and disadvantages and how it gets effected if I change it to TransactionManagementType.BEAN
ERROR:
Error updating database. Cause: java.sql.SQLException: javax.resource.ResourceException:
IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.
connectionmanager.listener.TxConnectionListener#680f2be0[state=NORMAL managed
connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection#7ba33a94 connection
handles=0 lastReturned=1495691675021 lastValidated=1495690817487
lastCheckedOut=1495691675018 trackByTx=false pool=org.jboss.jca.core.connectionmanager.
pool.strategy.OnePool#efd42c4 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool
#71656eec[pool=FAQuery] xaResource=LocalXAResourceImpl#4c786e85
[connectionListener=680f2be0 connectionManager=5c3b98bc warned=false
currentXid=null productName=Oracle productVersion=Oracle Database 12c
Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
jndiName=java:/FAQuery] txSync=null]
TransactionManagementType.CONTAINER
You let the container itself manage transactions(container will commit and rollback). You can control behavior of your transactions (more precisely transaction propagation) by annotating methods with #TransactionManagementAttribute and specifying one of the attributes from TransactionAttribute Types.
TransactionManagementType.BEAN
You have to do transaction demarcation (start, commit, rollback) explicitly yourself, by obtaining UserTransaction interface.
#Resource
UserTransaction ut;
public void method(){
ut.begin();
... // your business logic here
ut.commit(); // or ut.rollback();
}
Note that you have to either commit and rollback before you exit the same method which stated the transaction for Stateless and Message Driven Beans, but it is not required for Stateful bean.
Regarding your question, advantage of BMT is that scope of the transaction can be less than scope of the method itself, i.e explicit control of the transaction.
You would most probably use CMT, BMT is required only in some narrow corner cases to support specific business logic.
Another advantage or use case of BMT is if you need to use Extended Persistence Context Type, which can be supported in BMT with Stateful Session Beans.
Regarding your specific problem, without seeing any bean code or error messages, this is probably what is happening: if you have more databases then each database and its corresponding driver must be able to join an existing transaction, otherwise you will get a specific detailed error.
If you use TransactionManagementType.BEAN the bean is required to start a brand new transaction. Which means you are not joining an existing transaction, and each database operations begin and commit independently from each others.
You can achieve the same effect by leaving TransactionManagementType.CONTAINER and annotating your method with REQUIRES_NEW, provide of course you are calling each EJB trough the corresponding proxy/interface.
So it is not correct to put it like BEAN vs CONTAINER, but rather you have to made some design choice and annotate your methods accordingly.
As requested for a method marked with one of the following:
REQUIRES_NEW existing transactions gets suspended, and the method runs under a brand new transaction
REQUIRED is the default behavior, if a transaction exists it is reused by the method, otherwise gets created and the method runs in it
I am using Dao classes that subclasses HibernateDaoSupport.
I have seen examples which calls
getSession().save(instance)
as well as
getHibernateTemplate().save(instance)
what is the difference between these two?
getSession opens a new session
whereas the hibernatetemplate does a best effort to find an existing session/transaction.
Hibernate template is more effective way to database connection. for more info
click here
HibernateTemplate generally a helper class provided by spring hibernate support, to make it really convenient to get the Session & transactions and to commit the Transaction you need not to do it manually while in case of getSession() you need to manage transactions.
I want to know how to implement a JPA EntityManager per user thread design. Since EM are light weight objects, it should not be an overhead to create them per user thread. The problem I want to solve is a single JSP page with multiple (parallel) JSON/AJAX calls to back-end services (via controllers).
I am having an Entity Manager (with persistence context EXTENDED), with Open EM In View Filter. It does work nice, but only when there is one user thread (say, a json call) per page, or in other words when I access em in serial fashion.
It does not however solve my purpose when I call my services from multiple threads as em instances are shared and I get weird errors (sometimes shared access to collections, and sometimes closed connection, which are expected I believe).
I am using JPA over Spring 3 and hibernate 3.5. I inject an entity manager (extended) into my services as below:
#PersistenceContext(type = PersistenceContextType.EXTENDED)
protected EntityManager em;
My readonly service methods are annotated as
<tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
All other methods, are annotated as
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
I want to avoid an application managed em, and hence did not go for injecting a EntityManagerFactory instead.
Also, If I choose to inject EntityManager into spring controller, I will still have issues when same controller is called in parallel from two threads !
Is there an elegant way to achieve a thread safe access to em. I also want to avoid locking any entity objects, which complicates things further.
Since multiple ajax calls from same page is a very common design in modern web - applications, I believe there must be a simple and declarative way of achieving this (without going back to managing hibernate sessions manually with interceptors etc)
I don't quite understand your problem.
Entity manager per thread is a default behaviour, but you explicitly overrode it with EXTENDED. Do you have any specific reason for configuring it as EXTENDED? If not, all you need is to remove it:
#PersistenceContext
protected EntityManager em;
Spring has a Thread scope, which is disabled by default (See the section 4.5 Bean scopes):
Thread-scoped beans
As of Spring 3.0, a thread scope is available, but
is not registered by default. For more information, see the
documentation for SimpleThreadScope. For instructions on how to
register this or any other custom scope, see Section 4.5.5.2, “Using a
custom scope”.
If you activate the scope, you can just define your entitymanagers as scope=thread
This is the most standard way of working with EM/Sessions, and there are standard tools like OpenSessionInViewFilter (or Interceptor) which creates a session when HTTP Request comes into your servlet container.
Or it can be a Spring Transactional support which creates a session with the help of AOP.
The key point here is to use already existing mechanism or, if you have some extensions, at least copy-paste them.
Spring does this via binding/unbinding the resources to the thread with the help of TransactionSynchronizationManager. You can take a look at Spring sources or here is an example of session-per-conversation pattern which also uses the same means to bind resources to threads.
I had a few questions all related to the way an entity manager is created and used in an application with respect to Virtual Private Databases, which is a feature in Oracle DB which enables Row Level Security.
In a session bean, we generally have the entity manager as a member, and its generally injected by the container. How is this entity manager managed by the container - I mean, if we want to implement a Virtual Private Database then we have to make sure that the Virtual Private Database-context remains valid for the entire user session, and we do not have to set this context everytime before we fire a query. (to include more verbiage here : a session bean implements a couple of functions and each of these functions uses the same entity manager; now, it should not be the case that we set the Virtual Private Database everytime in each of these functions which do some DB manipulations).
Further to #1, since the entity manager is cached in the session bean, do we need to explicitly close the entity manager in any scenario? (like we do for JDBC connections?)
Also, I was wondering what should be the use case(or design criteria) for using a JTA or a non-JTA datasource. Is the way we create an entity manager dependant on this?
To add w.r.t the requirement on VPD:
It would be nice if the container managed EM can somehow be made to enforce the VPD per user. Note that EM is injected in here, so there should be a mechanism to set the VPD on the connection(and later retrieve the same connection for 'this' user in 'this' session).
Without an injected EM, i think using a reference to EMF and then setting the properties for the EM can be done. Something like :
((org.eclipse.persistence.internal.jpa.EntityManagerImpl)em.getDelegate()).setProperties
It would be an overkill, if the VPD is set everytime before the query is fired, rather the connection should 'maintain' the VPD context during the user's session and later release the connection (after clearing the VPD) back to the pool.
In a session bean, an injected entity manager is container managed and by default transaction scoped.
This means when you call any method on the session bean and a transaction is started, the persistence context of the entity manager starts. When the transaction is committed or rollbacked it ends. There is thus no scenario in which you have to explicitly close the entity manager.
Furthermore, when there already is a transaction in progress, this is joined by default and when there already is a persistence context attached to said transaction it's propagated instead of a new one being created.
Stateful session beans have another option, and that's the extended persistence context. This one is coupled to the scope of the stateful bean instead of to individual transactions. You still don't have to do any closing yourself here.
Then, you can also inject an EntityManagerFactory (using #PersistenceUnit) and then get an entity manager from it: In that case you'll have an application managed entity manager. In this case you'll have to explicitly close it.
JTA datasources (transactional datasources) are by default used with container managed entity managers. The container takes care of everything here. non-JTA datasources are for situations where you need separate connections to a DB, possibly outside any running transaction, on which you can set auto commit mode, commit, rollback, etc your self.
These two different datasource types can be defined in orm.xml for a persistence unit. If you define a persistence unit with a non-JTA datasource, you typically create an entity manager for it using a factory and then manage everything your self.
Update:
Regarding the Virtual Private Database, what you seem to need here is a user specific connection per entity manager, but the normal way of doing things is coupling a persistence unit to a general data source. I guess what could be needed here is a datasource that's aware of the user's context when a connection is requested.
If you completely bypass the container and even largely bypass the JPA abstraction, you could go directly to Hibernate. It has providers that you can register globally like DriverManagerConnectionProvider and DatasourceConnectionProvider. If you provide your own implementations for these with a setter for the actual connection, you can ask these back from a specific entity manager instance just prior to using it, and then set your own connection in it.
It's doable, but needless to say a bit hacky. Hopefully someone else can give a more 'official' answer. Best would of course if Oracle provided an official plug-in for e.g. EclipseLink to support this. This document hints that it does:
TopLink / EclipseLink : Support filtering data through their
#AdditionalCriteria annotation and XML. This allows an arbitrary JPQL
fragment to be appended to all queries for the entity. The fragment
can contain parameters that can be set through persistence unit or
context properties at runtime. Oracle VPD is also supported, include
Oracle proxy authentication and isolated data.
See also How to use EclipseLink JPA with Oracle Proxy Authentication.