Wednesday, February 4, 2015

Some information on Spring with hibernate

Spring:

Open source and light weight, Loose coupling, Container will manage the application objects. 
It provides the consistent transaction management and exception handling.
AOP: separates application business logic from system services.
Exception Handling: Spring provides a convenient API to translate technology-specific exceptions (thrown by JDBC, Hibernate, or JDO) into consistent, unchecked exceptions.

IOC in spring:

Spring container will responsible to create, maintain and destroy objects. Container will take the related information from metadata.In springs we can specific this meta information through XML or Annotation based and Java base(@configuration.). All so container uses dependency injection.
Can do unit test easy because of loose coupling.

Dependency Injection can achieve through Construction based or through setter.If it is a mandatory then we better choose construction based DInjection, else we can use setter based.

  • Spring object's can be configured in XML, Annotation based/java based configuration @configuraion and @ beans...etc,
  • There are two important bean life cycle methods we can override in spring beans: @PostConstruct and @PreDestroy

Method level Injection with spring (Injecting prototype model in to singleton model)

When we want to inject prototype model object into singleton object we will be having an issue.

How we can achieve this in spring? we have a concept calling method injection. All beans in the spring's are singleton by default,
meaning spring instantiates them during context creation,caches them in context, when ever it needed it will load from cache,
if you make a particular object scope as prototype and you want to inject this object into other singleton object the actual problem arrives.

Spring Architecture:

Spring Framework Architecture



Bean scopes in Springs:


All beans in a spring IOC default is singleton.

Here is list of available bean scopes in springs:

ScopeDescription
singletonThis scopes the bean definition to a single instance per Spring IoC container (default).[Singleton beans are not thread safe.]
prototypeThis scopes a single bean definition to have any number of object instances.
requestThis scopes a bean definition to an HTTP request. Only valid in the context of a web-aware Spring ApplicationContext.
sessionThis scopes a bean definition to an HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.
global-sessionThis scopes a bean definition to a global HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.


singleton beans are not thread-safe in Spring framework.

Spring with Hibernate Integration:
We can define resources such as SessionFactory ..etc as a beans in spring container
First to create a SessionFactory:
In applicationcontext.xml file write as below
<beans>

    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
        <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>

    <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="mappingResources">
            <list>
                <value>product.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.HSQLDialect
            </value>
        </property>
    </bean>

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory" />
</bean>
    
   <bean id="myProductDao" class="product.ProductDaoImpl">
        <property name="template" ref="mySessionFactory"/>
    </bean>

</beans>



Create Dao Layer :

public class ProductDaoImpl implements ProductDao {

    private HibernateTemplate template = null;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.template = new HibernateTemplate(sessionFactory);
    }

    public Collection<Person> findPersons() throws DataAccessException {
        return (Collection<Person>) template.find("from Person");
    }
}

To make annotation based transaction management use below command in applicationcontext.xml file.
<tx:annotation-driven/>

We can do transaction management in 3 ways:
1) Using spring AOP.
2) Declarative transaction management.
3) Programmatic transaction.

In this we are going to discuss about declarative transaction management:
To make Declarative transactions in Springs with hibernate follow below steps:

All you need to provide is the TransactionManager implementation and a "<tx:annotation-driven/>" entry.

Add the below code into your application context file make sure you mention <tx:annotaion-driver/>

<bean id="transactionManager"

            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <tx:annotation-driven/>

To handle multiple data source with different transactions:

public class TransactionalService {

    @Transactional("order")
    public void setSomething(String name) { ... }

    @Transactional("account")
    public void doSomething() { ... }
}
could be combined with the following transaction manager bean declarations in the application context.

<tx:annotation-driven/>

    <bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        ...
        <qualifier value="order"/>
    </bean>
    <bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        ...
        <qualifier value="account"/>
    </bean>

Transaction propagation: 

MANDATORY
Support a current transaction, throw an exception if none exists.
NESTED
Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
NEVER
Execute non-transactionally, throw an exception if a transaction exists.
NOT_SUPPORTED
Execute non-transactionally, suspend the current transaction if one exists.
REQUIRED
Support a current transaction, create a new one if none exists.
REQUIRES_NEW
Create a new transaction, and suspend the current transaction if one exists.
SUPPORTS
Support a current transaction, execute non-transactionally if none exists.

What is sorted collection and order collection in hibernate.

A sorted collection is sorted in-memory using java comparator, while order collection is ordered at the database level using order by clause

Developing a simple Rest service using spring 4

@RestController annotation which marks the class as a controller where every method returns Domain Object instead of a view.

@RestController
public class RestTestController {

    @RequestMapping("/sayHello")
    public Greeting sayHello(@RequestParam(value="name", defaultValue="World") String name) {
        return new Greeting(name);
    }
}

The above rest controller URL: http://localhost:8080/sayHello?name=Kiran

where as Request mapping has URL:sayHello and its accepting a parameter named name and the return type of this method is Object as said earlier all the methods inside a @RestController will return the domain object istead of view. The return type will automatically converted into JSON object.

This Greeting object contain a setter and getter method of name.

In the case of @Controller annotation you need to manually specify the @ResponseBody annotation to controller specifying and object is returning instead of a view.

No comments: