Using #Transactional with hibernate - java

I am using hibernate for the REST API. Right now all the transactions are handled by explicitly calling beginTransaction and transaction.commit. The transaction is rolled back in case of a failure. I am looking to use #Transactional instead of all the beginTransactions and commit transactions. Could someone tell me how can I integrate #Transactional in my hibernate. I am using mysql for querying the database.

You can annotate your query method with #Transactional so you get your transaction opened, commited and closed when your method ends.
Be careful about isolation levels (https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html#isolation--) because it indicates when Spring will create a new session for your transaction, or simply use already opened one.
When you thrown an exception on your method, transaction gets an automatic rollback and you're good :)

You can use Spring Framework with Hibernate Integration. The advantage is spring manages the Hibernate session's and all the low level things that we have to manage manually in hibernate like granular commit etc. Here is the example of this. this is older repository so uses older version of Spring and Hibernate but you can upgrade it here

Related

Use custom interceptor with JTA #Transactional (quarkus-narayana-jta)

I want to find a way to apply a custom interceptor with JTA #Transactional annotation.
I have a method with #Transactional which is one of business-transactions. In that method I want to:
do some database operation
publish some topic with a cloud messaging service.
If any of the two fails both of them should not be done (i.e. they should be rolled back).
Currently I use Google Cloud pubsub as the messaging service, but this library does not seem to be compatible with JMS or JTA. Therefore, I'm wondering if I can implement a custom interceptor for that library (e.g. queue messages during a transaction, and publish the queued messages when the transaction is successfully committed).
Is there any good idea to do that?
Framework is Quarkus, and the JTA implementation is Narayana for now.
No. JTA #Transactional requires your messaging platform to have a transaction manager that ideally support the XA API or at least some form of transactional semantics: begin(), commit() and rollback() - begin() might not be necessary, but definitely rollback() is.
If something goes wrong with the second message inside your transaction, you want to make sure that the first message 'disappears' as if it never happened and rollback the complete transaction.
But, as of now, Google pub/sub has no notion of transaction, transaction IDs or commit() and rollback().

Upgrading spring transaction from 1.2.5 to 4.1.1

Am facing an issue while upgrading spring from 1.2.5 to 4.1.1. With the spring1.2.5 spring was committing all my changes to the dao objects in the table without an explicit update query call. But after the upgrade changes is not getting persisted automatically.
Below is my value for my hibernate.transaction.jta.platform configuration
<prop key="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform</prop>
After debugging i found in the transaction interceptor class of spring transaction jar, commitTransactionAfterReturning method is being invoked which is committing all changes in the transaction. But am not able to find a equivalent method in the transaction interceptor class of spring transaction 4.1.1 jar. I do not want do explicit updates for all the changes & I want spring to handle them as it was performing in 1.2.5 version.
Please let me know how to handle the above scenario.

Transaction Management outside Data Access Layer

Data Access Layer is not responsible for transaction management am I correct? I have these DAO implementations: HibernateDAO and SqlDAO. If I will choose Hibernate and handle its transaction management at above layer, when I switch to SQL then I will change every single transaction management made by the Hibernate to SQL? This is bad right? What strategy will I gonna use in this case? TIA.
I've never worked on transactions outside of spring and JTA. Spring offers a transactions across several different platforms using transactions. You may want to check that out.
Also, I've seen JTA transactions work on ejb, Hibernate and Jms messages, but not sure if it will work for jdbc and hibernate, more on hibernate transactions here.

can you create your own JTA transaction?

I am loading a large set of data into a database from a webservice. I am using eclipslink for persistence and running the application on glassfish 3.0. I run into problems on my test data set in that there are a few foreign key constraint violations. I am fine with the violation, I do not want that data if it is not complete. My problem however comes in that the exception is thrown in the container. That then marks my transaction for a rollback, and I get no data at all then.
I would like to continue using JTA but am not sure if I can do what I want to achieve, and that is create my own JTA transaction so I can control when it commits,etc. I am not sure if that is a good idea though as I feel by doing so I may be destroying some of the benefits of using JTA.
So is it possible to get a JTA transaction?
Do the database work in a method of a session bean. Annotate that method with:
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
It will be given its own transaction. The outer transaction will be suspended while it does its stuff.
http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#Integrating_the_Unit_of_Work_with_an_External_Transaction_Servicestrong text**
Read How to Acquire a Unit of Work with an External Transaction Service. Apparently you can snatch the UserTransaction and/or start your own by querying the container JNDI for UserTransaction

Why does Spring Roo give persist() Propogation.REQUIRES_NEW

I've been looking at the code generated by Spring Roo and I noticed that the persist() method it creates is given Propagation.REQUIRES_NEW. Wouldn't the default propagation be sufficient?
#Transactional(propagation = Propagation.REQUIRES_NEW)
public void Entity.persist() {
if (this.entityManager == null) this.entityManager = entityManager();
this.entityManager.persist(this);
}
Some additional information. Here is the roo log that produced this code:
// Spring Roo 1.1.0.RELEASE [rev 793f2b0] log opened at 2011-02-04 10:01:02
project --topLevelPackage org.sotest.sscce --projectName Test --java 6
// Spring Roo 1.1.0.RELEASE [rev 793f2b0] log closed at 2011-02-04 10:01:04
// Spring Roo 1.1.0.RELEASE [rev 793f2b0] log opened at 2011-02-04 10:01:06
persistence setup --database GOOGLE_APP_ENGINE --provider DATANUCLEUS
entity --class ~.entities.Entity
exit
// Spring Roo 1.1.0.RELEASE [rev 793f2b0] log closed at 2011-02-04 10:02:55
I am using the GAE database with the DN provider. I simply created an entity, I did not touch any files other than issuing the above roo commands. When I open Entity_Roo_Entity.aj I get the above code.
I will try this again on the latest version of Roo and verify the same output. I will also post this issue on a Roo-related forum.
Update: The same code is generated with Roo 1.1.1 (latest version)
SECOND ANSWER (after additional info was added to question)
It's likely due to the use of GAE. The GAE datastore doesn't use traditional transaction semantics. See description of GAE's transaction isolation here. Specifically:
Queries and gets inside a transaction
are guaranteed to see a single,
consistent snapshot of the datastore
as of the beginning of the
transaction. ... This consistent
snapshot view also extends to reads
after writes inside transactions.
Unlike with most databases, queries
and gets inside a datastore
transaction do not see the results of
previous writes inside that
transaction. Specifically, if an
entity is modified or deleted within a
transaction, a query or get returns
the original version of the entity as
of the beginning of the transaction,
or nothing if the entity did not exist
then.
There are also restrictions on querying within a transaction. With this in mind, the REQUIRES_NEW is probably added so that any subsequent reads of the entity within the "first" transaction work as expected. Seems confusing and non-standard, but perhaps this is the best option when working in the constraints of GAE.
FIRST ANSWER
There must be a misunderstanding or something else at
play. I just checked with Roo v1.1.1
generating a simple entity with
Hibernate provider, and the default
transaction propagation is used. This
is also somewhat verified in the
documentation:
All persistence methods are configured
with Spring's Transaction support
(Propagation.REQUIRED,
Isolation.DEFAULT).
Using Propagation.REQUIRES_NEW would
not make sense for the default persist
methods.
I'm not an expert in Roo, so can't
even think of anything that might do
this. Perhaps you should post more of
your code, particularly any
non-standard configurations. Random
questions/ideas:
Are you using Hibernate provider or ?
Any custom configuration of the persisence-unit?
Do see the Propagation.REQUIRES_NEW on all of
your entity persist methods?
Where are you seeing the propagation annotation. (e.g. In the
*_Entity.aj file?)
Is there any chance that your entity class (or one of it's parents)
has it's own .persist method (thus
overriding Roo's generated method).
1:
http://static.springsource.org/spring-roo/reference/html/base-persistence.html
1: ah. I think it's highly likely to be due to use of the GAE/DN provider. I'll modify my answer accordingly. In the meantime, check out the notes around GAE's transaction isolation here: http://code.google.com/appengine/docs/java/datastore/transactions.html .

Categories

Resources