How can I replicate the rollback from Entity Manager with JPA Repository? - spring

I am converting a project from Spring framework to Spring boot, so I am no longer using persistence files and other config files.
Also, I gave up using Entity Manager, instead I created repositories which extend JPA Repository, so that I can use the functions from there. The only thing is that I have some unit tests and in the Spring framework, at the end of each test there is a finally clause which has a rollback, so that the data from the database to be specific to each test.
How can I do that without Entity Manager? I tried using the flush() method, but no result...

By default, data JPA tests are transactional and roll back at the end of each test.
You can refer to Enabling and Disabling Transactions in spring test documentation which indicate :
Annotating a test method with #Transactional causes the test to be run within a transaction that is, by default, automatically rolled back after completion of the test. If a test class is annotated with #Transactional, each test method within that class hierarchy runs within a transaction. Test methods that are not annotated with #Transactional (at the class or method level) are not run within a transaction. Furthermore, tests that are annotated with #Transactional but have the propagation type set to NOT_SUPPORTED are not run within a transaction.
Tips :
If you want to commit the transaction for a reason or another, you can use the #Commit annotation or less properly #Rollback(false) on method or class level.
If you want to execute code outside of a transaction ( before or after ) you can use #BeforeTransaction and #AfterTransaction on public methods that have no return ( return void ) or on default method of interfaces.

Related

Transaction - Springboot(JHipster) - RestService: how to

I have a microservice created with JHipster(SpringBoot+JPA) exposing a rest api.
During a save operation over an Entity I need to manage the transaction because I must execute another update over the DB (using other Entities).
How can I do this?
Using the tradictional approach (JDBC) I got the connection and create a transaction over it, make all the queries and finally close the transaction(commit/rollback).
With JPA I have an Entity, but I find no way to specify to begin/end(manage) the transaction programmatically.
You have many alternatives, here are few ones:
define a service (a class annotated with #Service) and annotate with #Transactional the public method that implements your logic
manage transaction manually through the EntityManager injected into your service class constructor
create a custom Repository
Check the Spring docs

How to rollback unit test while service layer is #Transactional

I am using Spring Boot 1.5.2.RELEASE and my service classes is annotated with
#Service
#Transactional(rollbackFor = Exception.class)
My unit test class is annotated with:
#RunWith(SpringRunner.class)
#SpringBootTest
I wish to roll back changes made in the database by unit test methods after test is finished.
One of the proposed solutions is to add #Transactional annotation over the test class, I tried it but this solution produces some issues, is that sometimes the test transaction is rolled back (even without no exceptions thrown!) before the service transaction is completed.
Is there another good solution to rollback test?
The solution with the #Transactional on the test class is the standard way of doing this. There is no way Spring Tx would roll back a transaction out of the blue, so I'd recommend looking closer into the issues that you encountered instead of inventing other solutions.
all changes will be rollbacked if didn't change default behaviour. And you don't have classes / methods with transaction propagation level = REQUIRES_NEW as it start independent transaction and can commit or rollback independently with the outer transaction
Transaction rollback and commit behavior
By default, test transactions will be automatically rolled back after
completion of the test; however, transactional commit and rollback
behavior can be configured declaratively via the #Commit and #Rollback
annotations.
#Rollback
#Rollback indicates whether the transaction for a transactional test
method should be rolled back after the test method has completed. If
true, the transaction is rolled back; otherwise, the transaction is
committed (see also #Commit). Rollback semantics for integration tests
in the Spring TestContext Framework default to true even if #Rollback
is not explicitly declared.
When declared as a class-level annotation, #Rollback defines the
default rollback semantics for all test methods within the test class
hierarchy. When declared as a method-level annotation, #Rollback
defines rollback semantics for the specific test method, potentially
overriding class-level #Rollback or #Commit semantics.
From the docs:
By default, test transactions will be automatically rolled back after
completion of the test; however, transactional commit and rollback behavior can be configured declaratively via the #Commit and #Rollback annotations.
Your comment:
sometimes the test transaction is rolled back (even without no
exceptions thrown !) before the service transaction is completed !
doesn't make sense to me. How did you know whether the txn completed or not if it was rolled back? Exceptions don't matter for tests, as I quoted the doc above.

Why doesnt #Transactional and #RequestMapping work together?

The moment I include the #Transactional annotation on a #RequestMapping, I notice in springboot that the url mappings do not auto-configure.
What could be responsible for this?
I want a case where (C)R(UD) rest calls work within a transaction.
If you're goal is to ensure your CRUD operations happen within a transaction, then using Spring Data JPA, this is done for you by default. Creating a repository interface that extends CrudRepository for example, your query methods will inherently be #Transactional. You can customize the #Transactional attributes by manually annotating a query method on your repository, but this need only be done if you want non default behaviour.
See the Spring Data JPA docs for more details.
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

Spring4 Junit4 Test: #TransactionConfiguration VS #Transactional, use only one or together?

In My junit test case:
I use only #transactional at class or one, each test method will roll back, because each method within running a transaction. And I add it at method, then the assigned method will roll back.
I use only #TransactionConfiguration(defaultRollback = true) at class, but the transaction is not work.
I use #transaction and #TransactionConfiguration(defaultRollback = true) at class together, also it will be roll back.
My issue:
Why roll back is not work with only #TransactionConfiguration at class?
I see #transactional default bean name is transaction manager and roll back is TRUE, so i only add it at class and not #TransactionConfiguration?
#transactional must annotation, is #TransactionConfiguration only assign transaction manager in multi-transactionManager case?
#transactional causes each method to be run within a transaction, and you can configuration, isolation etc by #transactional.
You can configuration transaction manager with #TransactionManager in multi-TransactionManager. So transaction is not work if you only use this annotation.
Because each method to be run within a transaction, then you can change it with #RollBack(false).
In https://docs.spring.io/spring/docs/4.3.x/javadoc-api/org/springframework/test/context/transaction/TransactionConfiguration.html, They say #TransactionConfiguration is "Deprecated" and "As of Spring Framework 4.2, use #Rollback or #Commit at the class level and the transactionManager qualifier in #Transactional".

Mule 3.3 spring 3.1 hibernate 3.6 transaction management

I am working on an application which involves mule, spring, hibernate with annotations. I am using org.springframework.orm.hibernate3.HibernateTransactionManager. Now the problem is :
I have certain components in mule which logs data into db based on conditions using hibernate. I have used #Transactional which inserts few data and then commits the transaction when the method scope is completed. But the behaviour which i want is : first component inserts data based on some condition, but the transaction should not commit immediately, again my second component that is a java class should insert some data again then third etc. if any of the component fails all the queries executed in all the components should be rolled back. all of this components are separate java classes
How can i achieve such behaviour.
thank you,
Let your whole component execution chain be in a transaction. then it will meet your expectation. it is easy to do it if all your components are in the same one spring appliction context. In the case, there are two things you need to do:
Add #Transactional annotation on your component class or specific methods which need to be in transaction. By default, transactional method use REQUIRED Propagation setting which will let all method in the exection chain merge to only one transaction.
Make sure Spring can scan all your components.
#Transactional
#Component( "lbsProviderApiCallJob" )
public class LbsProviderApiCallJoImpl implements LbsProviderApiCallJob, ApplicationContextAware {
If all your component are not in a spring context. it is complex to make it.

Resources