Reputation: 8067
I am new to Spring framework; need some clarifications on how the SessionFactory
object Dependency injection is working in below code.
spring-servlet.xml
<context:annotation-config />
<context:component-scan base-package="com.employee" />
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:employee.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
EmployeeDAOImpl.java
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class EmployeeDAOImpl implements EmployeeDAO {
@Autowired
private SessionFactory sessionFactory;
@Override
public void addEmployee(EmployeeForm employee) {
sessionFactory.getCurrentSession().save(employee);
}
}
How is the sessionFactory getting initialized with a SessionFactory object here?
What I understand
In the sprng-servlet.xml
file, the DI of sessionFactory
is happening in the below code:
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Now, if I open the source code for the class org.springframework.orm.hibernate3.HibernateTransactionManager
, then I can see the below section:
private SessionFactory sessionFactory;
public HibernateTransactionManager(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
afterPropertiesSet();
}
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public SessionFactory getSessionFactory(){
return this.sessionFactory;
}
which means the sessionFactory
class variable of org.springframework.orm.hibernate3.HibernateTransactionManager
has been initializd.
Now my Query:
In my code posted above, how is the sessionFactory
of class EmployeeDAOImpl.java
getting initialized? I can't find any relation between the sessionFactory
of class org.springframework.orm.hibernate3.HibernateTransactionManager
(where DI is happening) and the sessionFactory
of class EmployeeDAOImpl.java
(which I wrote). Then how is it working?
Please explain - totally confused !!!
Upvotes: 0
Views: 1517
Reputation: 398
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:employee.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
You have defined the session factory bean in you context file. During the application bootstrap, the spring context is loaded and this session factory bean is initialized by spring as a singleton instance.
<context:annotation-config />
<context:component-scan base-package="com.employee" />
@Autowired
private SessionFactory sessionFactory;
And since you have enabled the annotation-config and component-scan and declared @Autowired in your DAOImp, this is the reason Spring knows the place to inject the session factory bean properly.
This configuration is enabled the transaction manager annotation. Example:
@Transactional
public void addEmployee(EmployeeForm employee){...}
Here is the suggestion.
Transactional annotation is better to be placed in service layer instead of DAO layer. You need to make sure the annotation is placed on the concrete class unless you use the interface-proxy in your component-scan.
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
This piece of configuration is set the transaction manager bean which lets transaction manager knows which session factory it needs to manage with.
Therefore the configuration of bean
id="transactionManager" sets the transaction manager with the proper hibernate session factory.
tx:annotation-driven configuration enables the annotation-based transaction manager in code level.
Hope the explanation is helpful for you. :)
Upvotes: 1