Here is a short description on setting up a Spring with Hibernate Entitymanger (JPA) application.
I am asuming that you have a project structure ready
Step 1:
Create jpa configuration file:
repository-jpa.xml
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="osm" />
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="${database.platform}" />
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/nameDS" />
<property name="resourceRef" value="true" />
</bean>
NOTE: values like database.platform come from .properties i.e. a resource file
Example:
# DataSource Properties
database.platform=org.hibernate.dialect.Oracle10gDialect
database.driver=oracle.jdbc.driver.OracleDriver
database.url=jdbc:oracle:thin:@localhost:1521:xe
database.user=sa
database.password=sa
hibernate.hbm2ddl.auto=validate
This file is loaded as a resource:
configuration.xml
<bean id="gmPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>database.properties</value>
</list>
</property>
</bean>
Step 2:
You can create DAO / JPA classes. Here is a sample class I am using:
It is always a good idea to write a generic inteface for such classes
public interface IGenericRepository<E> {
void persist( E entity );
E merge( E entity );
void remove( E entity );
E findById( Long id );
void executeQuery( String strQuery );
List <E> executeNativeQuery( String strQuery );
EntityManager getEntityManager();
}
My concrete class:
@Transactional
@Repository
public class JpaGenericRepository<E> implements IGenericRepository <E> {
private Class <E> entityClass;
@PersistenceContext
private EntityManager entityManager;
@SuppressWarnings("unchecked")
public JpaGenericRepository() {
// Get "E" and assign it to this.entityClass
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
java.lang.reflect.Type type = genericSuperclass.getActualTypeArguments()[0];
if( type instanceof Class ) {
this.entityClass = (Class <E>) type;
} else if( type instanceof ParameterizedType ) {
this.entityClass = (Class <E>) ((ParameterizedType) type).getRawType();
}
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void persist( E entity ) {
entityManager.persist(entity);
int i =1/0;
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public E merge( E entity ) {
entity = entityManager.merge(entity);
return entity;
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void remove( E entity ) {
entityManager.remove(entityManager.contains(entity) ? entity : entityManager.merge(entity));
}
@Override
public E findById( Long id ) {
return entityManager.find(entityClass, id);
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 180)
public void executeQuery( String strQuery ) {
Query query = entityManager.createNativeQuery(strQuery, entityClass);
query.executeUpdate();
}
@Override
@Transactional
public List <E> executeNativeQuery( String strQuery ) {
Query query = entityManager.createNativeQuery(strQuery, entityClass);
@SuppressWarnings("unchecked")
List <E> rs = query.getResultList();
return rs;
}
@Override
public EntityManager getEntityManager() {
return entityManager;
}
}
Repository class as a service
public class JpaProductRepository extends JpaGenericRepository <Product> implements IProductRepository {
}
Now create an xml which has bean definations for the JpaProductRepository:
repository.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="false" default-dependency-check="none">
<bean id="productRepositry"
class="com.gide.csolp.osm.service.repository.jpa.JpaProductRepository" />
</beans>
That is preety much it!
If you have are developing a web application, then your application should load these xml’s via web.xml.
If you are creating a stand alone application you can uses any of the classes to load the application context.
Example application context:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-lazy-init="false" default-dependency-check="none">
<import resource="classpath:/META-INF/spring/repository.xml" />
<import resource="classpath:/META-INF/springtest/configuration.xml" />
<import resource="classpath:/META-INF/springtest/repository-jpa.xml" />
</beans>
38.307778
32.868611