I want to implement transaction using Spring's transaction management feature. But I'm not sure which is better(AOP vs #Transactional). Do both features work correctly? Is there any difference in development efficiency?
(Added)
Here AOP means "using AspectJ without using #Transactional annotation explicitly"
(Added)
I want to know difference of annotation-config and XML-based configuration
I've wondered this myself. I found a good discussion of this topic on the Spring forum.
Below I've summarize my take from the aforementioned link:
AOP Transactional Demarcation
Benefits:
Java code is devoid of transaction configuration which is contained instead outside of the code in configuration files
Java code has no direct dependencies on Spring libraries
Transaction management is centralized in one place
Can apply transactional boundaries to source code you can't easily modify
Drawbacks:
AOP complexity. It will not be clear from the code alone where transactional boundaries lie and developers may inadvertently break transactions by, for example, modifying method signatures where a pointcut is applied
The need to touch two locations (source code and AOP configuration) in order to apply transactional boundaries
#Transactional Spring annotation
Benefits:
Transactional boundaries are more clearly understood when examining the source code
Drawbacks:
Java code is coupled with transaction declaration (albeit only at the metadata level, but still a Spring import is required).
The discussion reminds me of JPA annotations versus JPA XML configuration. With XML based JPA configuration, entities are "cleaner", but is the separation worth the effort? Or perhaps even, is the separation harmful (it's nice to be able to open a java source file and know immediately based on the #Entity annotation that the class is an EJB)? In practice, it seems to me that most developers opt to use JPA annotations. Although, in this case unlike #Transactional, jpa annotations are a standard so that may help ease some concerns.
That said, I've been involved on projects were we've used Spring's AOP configuration to annotate a Struts2 (webwork) interceptor to allow a single transaction per request and this worked out great. In this case, we didn't really worry about transactional boundaries in our service layer or elsewhere -- everything was already participating in a transaction and since the view rendered before the interceptor closed the transaction, there was no need to apply an OpenSession/EntityManagerInView solution.
Related
What is the point of using spring transaction while we have database level transaction ?
If you use mysql, oracle or any other db in java, they provide methods to make things inside transaction then why spring transaction if I can do transaction using java DB driver methods ?
It's another layer of abstraction over the database transaction API. So if you wanted to use multiple databases with global transactions, Spring would allow you to do this. While I have never done it, I believe it would allow you to use DB2 and Hibernate together, for example.
Generally, what I've found is, if a feature is available in Spring, it's because there is a use case for it. They don't just put things into the framework without a reason.
Also, Spring provides declarative transaction demarcation, which produces more readable and maintainable Java code. The declarative approach lets us change the transaction strategy easily, without changing the code.
The Declarative transaction management approach allows you to manage the transaction with the help of configuration instead of hard coding in your source code. This means that you can separate transaction management from the business code. You only use annotations or XML based configuration to manage the transactions
We used Spring AOP along with Hibernate using this transaction strategy Here is an example, Spring AOP transaction mangement with Hibernate.
I'm a little confused by the mixed use of JSF2+Spring+EJB3 or any combination of those. I know one of the Spring principal characteristics is dependency injection, but with JSF managed beans I can use #ManagedBean and #ManagedProperty anotations and I get dependency injection functionality. With EJB3 I'm even more confused about when to use it along with JSF or if there is even a reason to use it.
So, in what kind of situation would it be a good idea to use Spring+JSF2 or EJB3+JSF2?
Until now I have created just some small web applications using only JSF2 and never needed to use Spring or EJB3. However, I'm seeing in a lot of places that people are working with all this stuff together.
First of all, Spring and EJB(+JTA) are competing technologies and usually not to be used together in the same application. Choose the one or the other. Spring or EJB(+JTA). I won't tell you which to choose, I will only tell you a bit of history and the facts so that you can easier make the decision.
Main problem they're trying to solve is providing a business service layer API with automatic transaction management. Imagine that you need to fire multiple SQL queries to perform a single business task (e.g. placing an order), and one of them failed, then you would of course like that everything is rolled back, so that the DB is kept in the same state as it was before, as if completely nothing happened. If you didn't make use of transactions, then the DB would be left in an invalid state because the first bunch of the queries actually succeeded.
If you're familiar with basic JDBC, then you should know that this can be achieved by turning off autocommit on the connection, then firing those queries in sequence, then performing commit() in the very same try in whose catch (SQLException) a rollback() is performed. This is however quite tedious to implement everytime.
With Spring and EJB(+JTA), a single (stateless) business service method call counts by default transparently as a single full transaction. This way you don't need to worry about transaction management at all. You do not need to manually create EntityManagerFactory, nor explicitly call em.getTransaction().begin() and such as you would do when you're tight-coupling business service logic into a JSF backing bean class and/or are using RESOURCE_LOCAL instead of JTA in JPA. You could for example have just the following EJB class utilizing JPA:
#Stateless
public class OrderService {
#PersistenceContext
private EntityManager em;
#EJB
private ProductService productService;
public void placeOrder(Order newOrder) {
for (Product orderedproduct : newOrder.getProducts()) {
productService.updateQuantity(orderedproduct);
}
em.persist(newOrder);
}
}
If you have a #EJB private OrderService orderService; in your JSF backing bean and invoke the orderService.placeOrder(newOrder); in the action method, then a single full transaction will be performed. If for example one of the updateQuantity() calls or the persist() call failed with an exception, then it will rollback any so far executed updateQuantity() calls, and leave the DB in a clean and crisp state. Of course, you could catch that exception in your JSF backing bean and display a faces message or so.
Noted should be that "Spring" is a quite large framework which not only competes EJB, but also CDI and JPA. Previously, during the dark J2EE ages, when EJB 2.x was extremely terrible to implement (the above EJB 3.x OrderService example would in EJB 2.x require at least 5 times more code and some XML code). Spring offered a much better alternative which required less Java code (but still many XML code). J2EE/EJB2 learned the lessons from Spring and came with Java EE 5 which offers new EJB3 API which is even more slick than Spring and required no XML at all.
Spring also offers IoC/DI (inversion of control; dependency injection) out the box. This was during the J2EE era configured by XML which can go quite overboard. Nowadays Spring also uses annotations, but still some XML is required. Since Java EE 6, after having learned the lessons from Spring, CDI is offered out the box to provide the same DI functionality, but then without any need for XML. With Spring DI #Component/#Autowired and CDI #Named/#Inject you can achieve the same as JSF does with #ManagedBean/#ManagedProperty, but Spring DI and CDI offers many more advantages around it: you can for example write interceptors to pre-process or post-process managed bean creation/destroy or a managed bean method call, you can create custom scopes, producers and consumers, you can inject an instance of narrower scope in an instance of broader scope, etc.
Spring also offers MVC which essentially competes JSF. It makes no sense to mix JSF with Spring MVC. Further Spring also offers Data which is essentially an extra abstraction layer over JPA, further minimizing DAO boilerplate (but which essentially doesn't represent the business service layer as whole).
See also:
What exactly is Java EE?
JSF Controller, Service and DAO
#Stateless beans versus #Stateful beans
There's no real easy answer here as Spring is many things.
On a really high level, Spring competes with Java EE, meaning you would use either one of them as a full stack framework.
On a finer grained level, the Spring IoC container and Spring Beans compete with the combination of CDI & EJB in Java EE.
As for the web layer, Spring MVC competes with JSF. Some Spring xyzTemplate competes with the JPA interfaces (both can use eg Hibernate as the implementation of those).
It's possible to mix and match; eg use CDI & EJB beans with Spring MVC, OR use Spring Beans with JSF.
You will normally not use 2 directly competing techs together. Spring beans + CDI + EJB in the same app, or Spring MVC + JSF is silly.
We are currently using Spring 3.2.3 + JPA (Hibernate). We use aspects for transaction support as opposed to annotations. We write out own entity services (read: repositories) to abstract the persistence away from our application.
I've read a lot about Spring Data and feel it would make our code considerably cleaner and more robust. I wonder though, are there any gotchas that I should consider before transitioning?
Thanks
If you're already on JPA the transition should be as easy as it can be: activate the repositories, point the infrastructure to your EntityManagerFactoryBean and off you go.
Transactions should just work fine as well. The annotation based usage within Spring Data is selectively activated for the repository beans only. They are configured to take part in existing transactions by default, so any custom larger scoped transaction setting should be in effect already.
I am a newbie to spring hibernate.
And I find 2 ways to handle transactions in Spring declaratively - ProxyFactoryBean using TransactionInterceptor or the #Transactional annotation.
How do we decide which one to prefer?
Is there any other way available for declarative transaction management too?
Advantages of annotaions way:
Annotations are directly visible in the code.
Advantages of xml way:
You can reuse the same conf between multiple beans
You can share some class between two applications and apply different transaction rules
I prefer annotations where it is possible. It saves a lot of time when you read the code (you do not need open one more file and check it periodically).
Other way for declarative transactions: use <aop:config> with <tx:advice>. See corresponding entry in official documentation. It is a variation of xml way that is more easy to do then ProxyFactoryBean (you do not need to wrap beans / declare transaction interceptor manually).
Hope this helps.
Extending spring based interfaces is discouraged as it unnecessarily couples the code with Spring. Does the same reasoning applies to annotations as well? We need to have them imported in the source code before using them.
I'll take the opposite viewpoint--of course using a Spring-specific annotation ties the class to Spring. I claim it's self-evident that importing and using Spring annotations ties the code to Spring (although you could trivially redefine those annotations for a non-Spring environment). The key for me is how deeply it's tied to Spring.
It's easier to check for, and process, annotations, than it is to restructure a class hierarchy or duplicate the functionality of a non-marker interface. Assuming you wanted to leave the annotations in, and could duplicate the logic behind the annotations, it'll be easier to do that (IMO) than to recreate whatever class/interface hierarchy implemented similar functionality.
The other key is the word "unnecessarily". I have yet to create a Spring application and need those classes outside of a Spring environment. When I have (generally for exposed APIs) it's been at the interface level. Note, however, that I knew from the onset that this exposure would exist and I planned accordingly.
Most would argue that this does not. While you've imported those annotations needed to ensure that Spring handles the request or wraps the transactions, you are not extending or implementing a specific class or interface.
Think about it this way, when you've annotated that class you're telling Spring to do various things based upon your configuration. Take out those annotations, and what you have is a POJO which just has some methods. It's a completely valid object without those annotations, it might not do what you wish it do (i.e. handle requests), but the code is still performing the same logic as it was with the annotations -- you are just now responsible for calling it appropriately.