object does not return updated optimistic locking version - spring

I've implemented optimistic locking and see that it is working fine. However, the object that is returned to my backing bean from the service has the previous version not the current one. If I do another "find" in another transaction I get the correct one. It's like the commit is happening after the transaction returns.
I'm using eclipseLink with Spring for transaction control.

How do you commit the transaction, and how do you return the object? If you are merging an object into the active EntityManager, then you need to return the object that you merge into, not from.

Related

How to deal with Spring hibernate no lock aquired exception inside a transaction

I have applied #Transactional in my interface, and inside my serviceImpl, the corresponding method is calling some other methods, one method is reading, another method is writing. Although I have anotated as Transactional, when I am giving concurrent request, my insert method is throwing org.hibernate.exception.LockAcquisitionException: error.
Another problem is, this insert method is a shared method and it performs the insert method like Dao.save(obj) . Dao.save() is a generic method So i can not do anything here. I have to apply something on interface to avoid no lock aquired exception.
Is it possible to tell wait untill lock is aquired? Or retry if transaction is failed? Or lock all the tables until the transaction is completed so that another request can not access the relevent resources?
My hibernate version is 3.x, And database is mysql 5.6
The best way to do this is,
Mark your methods transactional
In your mysql database settings set the transaction isolation level as SERIALIZABLE

Can the rollback of Spring declarative transaction be postponed

Question:
Is there a way to allow Spring declarative transaction to postpone the rollback on exception ?
Use case:
I have to process several entities together in a single transaction.
The result of processing a single entity are a few new records in the DB and a few updates to existing ones.
If processing of any of those entities results in an exception, the transaction needs to be rolled back. So, all entities must be processed successfully in order for transaction to be committed.
The twist: I want to detect all the entities for which processing ends up with exception in one go. I do not want to run processing once, fail on entity No5, fix the issues on entity No5, and then run processing again only to be greeted by an exception on entity No7.
So, what I am trying to achieve is to gather all the errors on entities that are in a faulty state and notify someone to fix them. Due to this, I want the transaction that encapsulates all entities processing to carry on till the last entity and only then I want a rollback to happen.
What I tried so far:
Using propagation = NESTED like this:
#Transactional
void processAllEntities() {
entities = fetchEntities();
for (entity : entities) {
processSingleEntity();
}
}
#Transactional(propagation = NESTED)
void processSingleEntity(entity) {
do stuff;
}
Please note that methods above are in different #Component annotated classes and processAllEntities() is invoked from a third class.
This failed because JpaDialect does not support savepoints.
I tried to switch to DataSourceTransactionManager as suggested in the javadoc of Propagation.NESTED but then nothing is persisted since this transaction manager seems to be JPA unaware and my whole model is mapped with JPA annotations and I'm using spring-data-jpa for persistence.
Any ideas and feedback are welcome. Thanks.

Does Hibernate 1st Cache work with HibernateTemplate?

I am trying to dive a little deeper into Hibernate cache and Spring's HibernateTemplate, and I am kinda confused by the following questions:
1) How does HibernateTemplate manages the Hibernate session? If I invokes methods such as "getHibernateTemplate().find" and "getHibernateTemplate().execute()", will everytime HibernateTemplate opens a new Hibernate session to process?
2) Hibernate 1st cache works in the scope of Hibernate session. In this regards, if HibernateTemplate always open a new session to exeucte/find, then does it mean the Hibernate 1st cache is NOT usable with HibernateTemplate? (because the cached object will be destroyed anyway, and the next find() has to make a fresh query to get everything again from DB)
3) It seems Hibernate 1st cache holds a map of all objects fetched during the life of a session. In this case, if I query a object which had been fetched before in the same session, then I should get the object and all its data directly from the cache? In this regards, what happens if the data of this object has been modified in the database?
4) Hibernate 1st cache returns the data in format of objects, in this regards, if I use HQL to fetch only a few columns (attributes) from a table (object), will those data (objects with only part of its attributes being filled) also be cached?
Thanks a lot!
-------------------------- Additional Info --------------------------
Thanks to the hint from Alessio, I re-checked the Spring specification and the following is my understanding:
If I call the getHibernateTemplate() within a existing transaction block (e.g., behind "session.beginTransaction();"), then HibernateTemplate will use the existing transaction to execute.
If I call getHibernateTemplate() with no transaction in current thread, then getHibernateTemplate() will actually call "openSession()" instead of "getCurrentSession()" because there is NO transaction (even when openSession() had been called before and an opened session was already bound to current thread), and a new session will be created and given to getHibernateTemplate(). Once the getHibernateTemplate has done its work, the newly created session will be destroyed.
Am my understanding right?
The Spring documentation says the following about session access and creation:
"HibernateTemplate is aware of a corresponding Session bound to the current thread, for example when using HibernateTransactionManager. If allowCreate is true, a new non-transactional Session will be created if none is found, which needs to be closed at the end of the operation. If false, an IllegalStateException will get thrown in this case."
So, whether it creates a new session or not depends on the allowCreate property and the presence of an interceptor that sets up a session for the current thread. Note also that HibernateTemplate is capable of falling back to Hibernate's SessionFactory.getCurrentSession().
-------------------------- Additional Info --------------------------
Edit: to answer to the additional question by the author, the documentation is not very explicit about this, but a session is obtained or created when getSession() is called, which includes calls to execute() of course. A session is not created or accessed in any way when you only instantiate a HibernateTemplate or get it from an application context, as the call to getHibernateTemplate() presumably does.

Spring Bean Hangs on Method with #Transactional

Just a little background , I'm a new developer who has recently taken over a major project after the senior developer left the company before I could develop a full understanding of how he structured this. I'll try to explain my issue the best I can.
This application creates several MessageListner threads to read objects from JMS queues. Once the object is received the data is manipulated based on some business logic and then mapped to a persistence object to be saved to an oracle database using a hibernate EntityManager.
Up until a few weeks ago there hasn't been any major issues with this configuration in the last year or so since I joined the project. But for one of the queues (the issue is isolated to this particular queue), the spring managed bean that processes the received object hangs at the method below. My debugging has led me to conclude that it has completed everything within the method but hangs upon completion. After weeks of trying to resolve this I'm at end of my rope with this issue. Any help with this would be greatly appreciated.
Since each MessageListner gets its own processor, this hanging method only affects the incoming data on one queue.
#Transactional(propagation = Propagation.REQUIRES_NEW , timeout = 180)
public void update(UserRelatedData userData, User user,Company company,...)
{
...
....
//business logic performed on user object
....
......
entityMgr.persist(user);
//business logic performed on userData object
...
....
entityMgr.persist(userData);
...
....
entityMgr.flush();
}
I inserted debug statements just to walk through the method and it completes everything including entityMgr.flush.().
REQUIRES_NEW may hang in test context because the transaction manager used in unit testing doesn't support nested transactions...
From the Javadoc of JpaTransactionManager:
* <p>This transaction manager supports nested transactions via JDBC 3.0 Savepoints.
* The {#link #setNestedTransactionAllowed "nestedTransactionAllowed"} flag defaults
* to {#code false} though, since nested transactions will just apply to the JDBC
* Connection, not to the JPA EntityManager and its cached entity objects and related
* context. You can manually set the flag to {#code true} if you want to use nested
* transactions for JDBC access code which participates in JPA transactions (provided
* that your JDBC driver supports Savepoints). <i>Note that JPA itself does not support
* nested transactions! Hence, do not expect JPA access code to semantically
* participate in a nested transaction.</i>
So clearly if you don't call (#Java config) or set the equivalent flag in your XML config:
txManager.setNestedTransactionAllowed(true);
or if your driver doesn't support Savepoints, it's "normal" to get problem with REQUIRES_NEW...
(Some may prefer an exception "nested transactions not supported")
This kind of problems can show up when underlying database has locks from uncommitted changes.
What I would suspect is some other code made inserts/deletes on userData table(s) outside transaction or in a transaction which takes very long time to execute since it's a batch job or similar. You should analyze all the code referring to these tables and look for missing #Transactional.
Beside this answer, you may also check for the isolation level of your transaction — perhaps it's too restrictive.
Does the update() method hang forever, or does it throw an exception when the timeout elapses?
Unfortunately I have the same problem with Propagation.REQUIRES_NEW. Removing it resolves the problem. The debugger shows me that the commit method is hanging (invoked from #Transactional aspect implementation).
The problem appears only in the test spring context, when the application is deployed to the application server it works fine.

EJB 3 Transaction attribute for read only method

I have a method that returns lot of data, should I use #TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) for this method. The method perform a JPA query an loads the full content of a table (about 1000 rows).
The client to this method - is that already in a transaction? When you use NotSupported the caller transaction will be suspended. If not I would say, just put Never as the transaction type. Never is better since callers know they are not supposed to call this method from inside a transaction. A more straight forward contract.
We always use Never for methods that do more processing so that developers are aware right off the bat not to call if they are involved in a transaction already. Hope it helps.
I would care to disagree as it seldom happens that user is not in a transaction in almost all the systems. The best approach is to use NOT SUPPORTED so that the transaction is suspended if the caller is in any transaction already. NEVER is troublesome unless you have a series of calls which are all in NO TRANSACTION scope. In short, NOT SUPPORTED is the type one should use.
As far as I know (at least this is the case with Hibernate), you cannot use JPA outside of a transaction as the entity manager's lifecycle is linked to the transaction's lifecycle. So the actual method that does the query must be transactional.
However, you can set it to TransactionAttributeType.REQUIRES_NEW; this would suspend any existing transaction, start a new one, and stop it when the method returns. That means all your entities would be detached by the time they reach the caller, which is what it sounds like you're trying to achieve.
In more complex systems, it pays to completely separate your data layer from your business layer and create a new set of object. Your method will then call the JPA query, then use the entities returned to populate objects from your business layer, and return those. That way the caller can never get their hands on the actual JPA entities and you are free to do in your data layer what you want, since now it's just an implementation detail. (Heck, you could change the database call to a remote API call and your caller wouldn't have to know.)

Resources