I have been googling for several hour now trying to find an example on how to write a service method that doesn't use Springs Hibernate Template while using a DAO interface. Something that is also confusing me is what happens when I put the #Transactional annotation in the service layer as opposed the DAO. Are the Service methods/DAO interfaces interchangeable?
Here is an example where the #Transactional is in the DAO
Here is one with the #Transactional in the Service Layer but using hibernate templates
Thanks for your help!
The Spring documentation recommends avoiding HibernateTemplate completely, and use the Hibernate API directly instead:
NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can
also be coded in plain Hibernate style. Hence, for newly started
projects, consider adopting the standard Hibernate3 style of coding
data access objects instead, based on
SessionFactory.getCurrentSession().
And the #Transactional annotation should always be put on methods of the service layer. This is the layer that demarcates transactions.
Read http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#orm-session-factory-setup to understand how to setup a session factory. Once done, the session factory can be injected in your DAOs:
#Repository
public class MyDAO {
#Autowired
private SessionFactory sessionFactory;
...
}
Related
The recommended way of executing SQL queries is by creating a repository, using the #Repository annotation. I'm wondering if I can also execute SQL queries within a service, using the #Service annotation, or is this tied to a specific Spring stereotype?
For example: Is there any rule that guarantees that a #Service class must have business logic and #Repository must have query execution? If I execute a query in a #Service class will it throw any exception?
No it won't throw any exception.
But the idea of separating the DB Logic and Business Logic is to use #Service for service implementations (business logic) and #Repository for repositories i.e to handle DB operations (it can be CRUD, PagingAndSorting etc).
Thus, the code becomes modular and obeys the design patterns and coding standards. Service will make use of Repositories. And your handlers will use methods from your Service. That's how it works.
As per the Spring API specification.
A class annotated with #Repository is eligible for Spring
DataAccessException translation when used in conjunction with a
PersistenceExceptionTranslationPostProcessor. The annotated class is
also clarified as to its role in the overall application architecture
for the purpose of tooling, aspects, etc.
So DataAccessException aims user code find and handle the kind of error encountered without knowing the details of the particular data access API in use (e.g. JDBC).
#Service does not have any DataAccessException translation thus you can expect un-translated exception on classes which are annotated with #Service annotation. It indicate that a class is a Business Service Facade.
#Service ,#Repository,#Controller are specialization of #Component are all termed as Spring Beans
#Component generic stereotype for any Spring-managed component
#Repository stereotype for persistence layer
#Service stereotype for service layer
#Controller stereotype for presentation layer (spring-mvc)
It's all about distributing the concerns (Presentation,Business,Database),so it won't through any exception as asked by you.
You can refer here for more-Spring Docs
It will not through any exception there are some specification of each annotation.THIS answer will give you more clarity hope it will help you.
When we are going to develop any Project it should be lossy coupled and maintainable. To achieve this layer separation is important
#Service - Annotate all your service classes with #Service. This layer knows the unit of work. All your business logic will be in Service classes. Generally, methods of service layer are covered under a transaction. You can make multiple DAO calls from service method. if one transaction fails all transactions should rollback.
#Repository - Annotate all your DAO classes with #Repository. All your database access logic should be in DAO classes.
#Component - Annotate your other components (for example REST resource classes) with component stereotype.
Reasons to use them :
The main advantage of using #Repository or #Service over #Component
is that it's easy to write an AOP pointcut that targets, for
instance, all classes annotated with #Repository.
You don't have to write bean definitions in context xml file. Instead
annotate classes and use those by autowiring.
Specialized annotations help to clearly demarcate application layers
(in a standard 3 tiers application).
What is Stereotype Refer Here
#Component generic stereotype for any Spring-managed component
#Repository stereotype for persistence layer
#Service stereotype for service layer
#Controller stereotype for presentation layer (spring-mvc)
For More Details Click Here and Here
For personal education I am currently developing a little application framework around Guice to learn-by-doing how Spring etc. work behind the scenes.
Intro
Just for the sake of context, here is what I have so far and plan to do so you get a feeling for what I try to archive:
Context (Core)
ApplicationContext/-Configuration
Modules (auto discovered, setting up the Guice bindings)
Extensions
Config: #Config
Locale: #Locale and i18n services
Resources: #Property, #Resource and some classes providing easy access to resources
Persistence: Problems - there we go!
Question
I'd like to use the JDO standard (and its reference implementation DataNucleus) for the persistence layer. Setting up the PersistenceManagerFactory was easy, so was using it in a basic manner. I am however targeting a typical service / repository layer architecture, e.g.:
Person
PersonRepository (JDO)
PersonService (Transactions, using PersonRepository)
That alone wouldn't be too hard either, but as soon as I tried properly integrating transactions into the concept I got a bit lost.
Desired
class PersonService {
#Transactional(TxType.REQUIRED)
public Set<Person> doX() {
// multiple repository methods called here
}
}
class PersonRepository {
private PersistenceManagerFactory pmf;
public Set<Person> doX() {
try (PersistenceManager pm = pmf.getPersistenceManager()) {
pm.....
}
}
}
Difficulties
DataNucleus supports RESOURCE_LOCAL (pm.currentTransaction()) as well as JTA transactions and I would like to support both as well (the user should not have to distinguish between the two outside the configuration). He should not have to bother about transaction handling anyway, that is part of the annotation's method interceptor (I guess).
I'd love to support the #Transactional (from JTA) annotation that can be placed on service layer methods. Knowing that annotation is not per-se available in JDO, I thought it could be made usable as well.
How exactly should the repository layer "speak" JDO? Should each method get a PersistenceManager(Proxy)from the PersistenceManagerFactory and close it afterwards (as in the example) or get a PersistenceManager injected (rather than the factory)? Should each method close the PersistenceManager (in both scenarios)? That would not work with RESOURCE_LOCAL transactions I guess since a transaction is bound to one PersistenceManager.
What I tried
I have a JDOTransactionalInterceptor (working with pmf.getPersistenceManagerProxy) and a JTATransactionalInterceptor (very similar to https://github.com/HubSpot/guice-transactional/blob/master/src/main/java/com/hubspot/guice/transactional/impl/TransactionalInterceptor.java working with a ThreadLocal)
Summary
I am aware that my question may not be as clear as desired and mixes the service / repository layer questions (which is my main problem I think) and transaction stuff (which I could figure out once I understand how to properly use PMF/PM in repository layer I think)
There is no scope à la RequestScoped etc. I just want the first #Transactional method call to be the starting point for that whole thing (and that is the point: Is this impossible and the PMF/PM have to be scoped before and I have to direct my thinkings into that direction?)
Thanks for any clarification / help!
We use HibernateTemplate in our DAOs for all the CRUD operations.
My question is, we use spring #Transactional on the services, Because the spring is managing the transactions, how does the HibernateTemplate behave in the senario where I update multiple DAOs. Meaning does HibernateTemplate use same session across different DAOs when Spring #Transactional is used?
#Transactional
public boolean testService(SObject test)[
dao1.save(test.getOne());
dao2.save(test.gettwo());
}
This is how the DAO class looks:
public class GenericHibernateDao<T, PK extends Serializable> extends HibernateDaoSupport
.
.
.
public PK save(T newInstance) {
return (PK) getHibernateTemplate().save(newInstance);
}
The HibernateTransactionManager javadoc is pretty clear about this:
This transaction manager is appropriate for applications that use a single Hibernate SessionFactory for transactional data access, but it also supports direct DataSource access within a transaction (i.e. plain JDBC code working with the same DataSource). This allows for mixing services which access Hibernate and services which use plain JDBC (without being aware of Hibernate)! Application code needs to stick to the same simple Connection lookup pattern as with org.springframework.jdbc.datasource.DataSourceTransactionManager (i.e. DataSourceUtils.getConnection or going through a TransactionAwareDataSourceProxy).
You're fine as long as you are accessing the connection through helper classes that are aware of the connection proxy such as DataSourceUtils (and the JdbcTemplate uses that behind the hood)
I was going through the hibernate tutorial and noticed that in every dao you have to get session,begin transaction.Perform all operations and then commit
private void createAndStoreEvent(String title, Date theDate) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
//Perform operations...
session.getTransaction().commit();
}
Then i have noticed in a framework called Appfuse which uses hibernate have dao methods as shown below.I dont see the begintransaction and commit
public List<Person> findByLastName(String lastName) {
//begintransaction
return getHibernateTemplate().find("from Person where lastName=?", lastName);
//Commit
}
I wonder how appfuse is wrapping up the dao operations with session.beginTransaction() and session.getTransaction().commit();
By using this technique the programmer doesn't have to bother about hibernate transaction stuff.I want it in such a a way that even if dao methods are overridden the transaction wrapper code should automatically come.
I have tried passing dao to a decorator class and wrapping the dao method call inside decorator class.But since the dao interface methods will change,the idea dint worked.How exactly we can achieve this.
I don't know how AppFuse is doing it, but a very common way of introducing transaction management into the service layer of an application is by using Aspect Oriented Programming. If you're using the Spring Framework, this (from the manual) is a good reference.
HibernateTemplate is part of Spring. You can read more about it at this link. But starting with Spring 3.0, it's considered to be deprecated in favor of declarative transaction management.
First, we create classes that represent db entities, ok, done.
Let's say we use Hibernate session factory and JPA annotations.
Now we must create a DAO: getUserById, getAllUsers() etc.
What do you recommend about transaction management, session factory, how a good design to be made?
Make the DAO generic. See the Don't repeat the DAO article.
Transaction management should be spring-managed. Use a JpaTransactionManager. Transactions can be marked in two ways, and they should mark methods of the service classes, not the DAO:
using #Transactional on each transactional method (in combination with <tx:annotation-driven /> in applicationContext.xml)
using <tx:advice> and the appropriate <aop:config>
Use OpenEntityManagerInViewFilter or OpenEntityManagerInViewInterceptor in order to avoid LazyInitializationException
Read this for more details.