Spring Hibernate #Transactional clarifications - java

I got a lot of confusion about #Transactional annotation.
1) If I use just declarative approach, is it enough to mark my service class/methods as #Transactional, or should I create the configuration beans and properties as shown in this Baeldung article?
2) I need to use even programmatical approach in some situations, to be able to explicitly call flush() at a specific point of my workflow. In this case the former definitions of hibernate configs are mandatory?

If you're on a Spring Boot project, no, you won't need to explicitly declare the SessionFactory or the PlatformTransactionManager Beans. They'll be auto-configured for you.
Yes, putting the Transactional annotation on your class or method is enough for transactions to take place. Auto-commit should even be turned off automatically (for optimization purposes), in case it's not done at DataSource level.
For the "programmatical" part, you should consider staying on the annotation side. You can play with the transaction propagation strategies to isolate certain operations.
A couple important notes about using the declarative, annotation approach.
Remember to annotate public methods, if possible. Any other method visibility cannot be managed via Java proxies or CGLIB proxies, thus, even though you won't notice it, those methods won't participate in the transaction context. For protected or private methods, you're forced to use AspectJ.
Remember also that when using proxies, self-invocation (& expecting a new transaction) doesn't work.
To use the programmatic approach, you just need to Autowire the TransactionTemplate or PlatformTransactionManager Bean.
The PlatformTransactionManager allows for more customization of the transaction, while TransactionTemplate is more of a utility object (which however can be modeled as needed).
Obviously, don't mix both approaches in the same methods call stack.

Related

Understanding Spring and "No EntityManager with actual transaction available"

I have a Spring Boot application with Hibernate, with a bunch of DAOs annotated with #Repository and Spring's #Transactional. Everything works fine. Then I decide to move common methods (persist, find, merge) to an AbstractDao. Writing operations (persist, merge) start throwing that No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call exception. I try adding #Transactional to AbstractDao, and contrary to my expectations, it fixes it.
Why is that so? I thought that since, unlike CGLIB, Spring uses interfaces instead of extending classes, it wouldn't work, and I would need to define an interface to declare instead of my DAOs. But I also guess that I'm mixing concepts of how Spring deals with dependency management and with transactions.
Can somebody provide an explanation of why does it work? Is there a better way of dealing with this problem?

Is it recommended to use the Spring's predefined InitializingBean and DisposableBean callbacks or not?

Is it recommended to use the Spring's predefined InitializingBean and DisposableBean callbacks or own init-method and destroy-method for initialization and cleanup.
I just started learning Spring Framework and I confused with the follwing statements that,
It is recommended that you do not use the InitializingBean or DisposableBean callbacks, because XML configuration gives much flexibility in terms of naming your method. (From a Tutorial Blog)
It is recommended to use Spring's predefined InitializingBean or DisposableBean callbacks. (From my Tutor)
Are both valid based on the scenario?
I believe it is just a matter of choice on how much you want to be "intruded" by Spring.
Personally, I use those Spring callback interfaces for Spring-related classes, for example, factory beans, aspects, bean post-processors, etc.
For things that should be neutral to container, I would rather having my own methods for initialization etc.
That means, I prefer a mixture of both.
The first one doesn't force your class to implement a Spring-proprietary interface, but recommends using XML to configure your beans. XML is, quite frankly, awful, and Spring has provided Java configurations or simple annotations for a long time, that allows removing the need for verbose, cumbersome, unsafe XML configuration.
I would simply use standard PostConstruct and PreDestroy annotations for this.
Yes. It is pretty clearly explained in the Spring documentation.
The JSR-250 #PostConstruct and #PreDestroy annotations are generally
considered best practice for receiving lifecycle callbacks in a modern
Spring application. Using these annotations means that your beans are
not coupled to Spring specific interfaces. For details see Section
5.9.7, “#PostConstruct and #PreDestroy”.
If you don’t want to use the JSR-250 annotations but you are still
looking to remove coupling consider the use of init-method and
destroy-method object definition metadata.

Spring's JdbcTemplate and Transactions

When using JdbcTemplate, do I need to explicitly configure transactions?
My code layout looks like the following:
I will have a UserDao that will be injected into my UserService, and then my Controllers will make calls on methods in my UserService.
I want to keep things as simple as possible transaction wise, and I don't need multiple database calls to span a transaction.
By default, do I have to do anything in my configuration file or use a #Transaction annotation anywhere?
Now say in my controller I need to make 2 calls on my userService and accountService, could I explicitly wrap it in a transaction somehow?
userService.updateUser(user);
accountService.updateXXX(...);
Yes, JdbcTemplate is not a substitute for transaction management. You still benefit from database transactions, so userService.updateUser will operate in a database transaction, but if accountService.updateXXX fails, userService.updateUser will not rollback.
If you don't want to use AOP, you can use TransactionTemplate instead. See programmatic transaction management in the Spring Reference Documentation.
One pattern I've seen before is for the MVC controller class to invoke a business service, which encapsulates the operation. The method of the business class could then be annotated #Transactional.
If your controller wants to do several things with users and accounts and have all that happen within one transaction, then you should have a service with one method that does all that stuff. Creating one service per DAO is not a great idea, because you end up with do-nothing wrappers around DAOs and processing will be slow because the database will have to create a separate transaction for each call to a DAO, you're making it do a lot more work than it should have to.
The service should provide functionality to the controller or whoever else is calling it. I try to create services with the idea that the service provides specific functions useful to a certain type of user.

Is it better to instantiate a new JdbcTemplate in every query or to inject a single one everywhere?

I have a Java library where I access the DB via JDBC using Spring's JDBC support. This library contains approximately a DAO class for each table I need to access, which are over a hundred. Currently I instantiate a new JdbcTemplate, or one of its variants, each time I need to perform a new query. Is this considered good practice or should I reuse a single JdbcTemplate as much as I can? I've actually seen examples of both approaches in either books or online documentation.
The context is a J2EE application, but ideally the code should be usable in different contexts, e.g. in offline tests or command line support tools.
Inject one, why bother instantiating? (It's unclear if you mean "instantiate through the Spring context" or "instantiate using new".)
Most samples I've seen do this in the config, I'm not even sure I've seen them instantiated manually outside of demo/test code. I see little benefit to doing it manualy, and zero if done outside of Spring.
Although there isn't a lot of overhead involved in creating a new JdbcTemplate, there isn't much of a point. The JdbcDaoSupport class, an abstract class useful for handling JdbcTemplate based DAOs consistently allows each DAO to either inject a DataSource (and undernear the covers instantiates a JdbcTemplate based on that DataSource) or inject a JdbcTemplate. Since you can do either you would only do the latter if you were looking to customize your JdbcTemplate by setting one or more of the following properties:
fetchSize
ignoreWarnings
maxRows
nativeJdbcExtractor
queryTimeout
skipResultsProcessing
exceptionTranslator
You would likely have one JdbcTemplate for each combination of these properties. All of these do have defaults, so its only necessary to set them if you are going to override them. Depending on the diversity of your DAOs, you may have one or many. Or in the case of extending JdbcDaoSupport, you may have none, having each DAO just wrap the datasource in a default JdbcTemplate undernearth the covers.
Instances of the JdbcTemplate class are thread safe once configured, so you can configure a single instance of a JdbcTemplate and then safely inject this shared reference into multiple DAOs (or repositories). For more information: JdbcTemplate-idioms

Rollback transactions in JAX-RS

I have a simple resource class that implements some POST method. How to rollback transaction if there was exceptions in my methods, and commit - if all is ok?
Is there a way to write this code once - not in every resource class that I have?
If you are using Spring, #Transactional will handle your scenario.
http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html
Using a dependency-injection will greatly simplify this. Using #Transactional or similar annotations around the methods where you want to commit/rollback transactions.
If you have to do this manually, you have basically two options:
do it manually for every operation
use the proxy pattern/decorator pattern and proxy/decorate all your classes that require transactions. Then in the proxy/decorator start the transaction, delegate to the target, and commit it after it returns. (this is how DI frameworks do it)

Categories