In this blog I’m going to implement spring jpa using eclipleLink.
First of all add the following snippet to your pom.xml
<dependencies> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.0.0</version> <scope>compile</scope> ... </dependency> </dependencies> ... <repositories> <repository> <id>EclipseLink Repo</id> <url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo</url> <!-- use this for javax.persistence <snapshots> <enabled>true</enabled> </snapshots> --> </repository> ...
After I copied all classes generated through hibernate in a package named com.biancama.spring3.model.eclipselink
.
I’ve done that because date
fileds must be annoted with @Temporal
So I create a structure of classes to have CRUD functionality
package com.biancama.spring3.dao; import java.io.Serializable; public interface CRUDAccess <K extends Serializable, E> { public K getKey(E entity); public E merge(E entity); public void persist(E entity); public void remove(E entity); public E findById(K id); }
package com.biancama.spring3.dao.eclipselink; import java.io.Serializable; import java.util.List; import java.util.Map; import org.eclipse.persistence.expressions.Expression; import org.eclipse.persistence.queries.DatabaseQuery; import org.eclipse.persistence.queries.ReadAllQuery; import com.biancama.spring3.dao.CRUDAccess; public interface EclipseLinkCrudAccess<K extends Serializable, E> extends CRUDAccess<K, E> { List<E> executeNamedQuery(String queryName, Map<String, Object> parameterMap); List<E> executeNamedQuery(String queryName); int getCount(String countField, Expression expr); List<E> executeReadAllQuery(ReadAllQuery readAllQuery, int first, int rows); List<E> executeDatabaseQuery(DatabaseQuery q); int deleteById(K id); }
package com.biancama.spring3.dao.eclipselink; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.math.BigDecimal; import java.util.List; import java.util.Map; import javax.persistence.Query; import org.eclipse.persistence.expressions.Expression; import org.eclipse.persistence.jpa.JpaEntityManager; import org.eclipse.persistence.queries.DatabaseQuery; import org.eclipse.persistence.queries.ReadAllQuery; import org.eclipse.persistence.queries.ReportQuery; import org.eclipse.persistence.queries.ReportQueryResult; import org.eclipse.persistence.sessions.Session; import org.springframework.orm.jpa.support.JpaDaoSupport; import org.springframework.stereotype.Repository; @Repository public abstract class EclipseLinkCrudAccessAbstractJPASupport<K extends Serializable, E> extends JpaDaoSupport implements EclipseLinkCrudAccess<K, E> { private final Class<E> persistentClass; protected EntityManager entityManager; @SuppressWarnings("unchecked") public EclipseLinkCrudAccessAbstractJPASupport() { this.persistentClass = (Class<E>) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[1]; } protected Class<E> getEntityClass() { return persistentClass; } @Override public E merge(E entity) { return getJpaTemplate().merge(entity); } @Override public void persist(E entity) { getJpaTemplate().persist(entity); } @Override public void remove(E entity) { getJpaTemplate().remove(entity); } @Override public E findById(K id) { return getJpaTemplate().find(getEntityClass(), id); } @SuppressWarnings("unchecked") @Override public List<E> executeNamedQuery(String queryName, Map<String, Object> parameterMap) { Query query = getJpaTemplate().getEntityManager().createNamedQuery( queryName); if (parameterMap != null) { for (String param : parameterMap.keySet()) { query.setParameter(param, parameterMap.get(param)); } } return query.getResultList(); } @Override public List<E> executeNamedQuery(String queryName) { return executeNamedQuery(queryName, null); } @SuppressWarnings("unchecked") @Override public int getCount(String countField, Expression expr) { ReportQuery query = new ReportQuery(getEntityClass(), null); query.setSelectionCriteria(expr); query.addCount("count", query.getExpressionBuilder().get(countField) .distinct()); List<ReportQueryResult> result = (List<ReportQueryResult>) getSession() .executeQuery(query); ReportQueryResult reportQueryResult = result.get(0); BigDecimal count = (BigDecimal) reportQueryResult.getResults().get(0); return count.intValueExact(); } protected Session getSession() { if (entityManager == null) { entityManager = getJpaTemplate().getEntityManagerFactory() .createEntityManager(); } return ((JpaEntityManager) entityManager.getDelegate()) .getActiveSession(); } @Override public List<E> executeReadAllQuery(ReadAllQuery readAllQuery, int first, int rows) { readAllQuery.setFirstResult(first); readAllQuery.setMaxRows(first + rows); return executeDatabaseQuery(readAllQuery); } @SuppressWarnings("unchecked") @Override public List<E> executeDatabaseQuery(DatabaseQuery q) { List<E> resultList = (List<E>) getSession().executeQuery(q); return resultList; } }
package com.biancama.spring3.dao.eclipselink; import com.biancama.spring3.model.eclipselink.Employees; public interface EmployeesDao extends EclipseLinkCrudAccess<Integer, Employees> { }
package com.biancama.spring3.dao.eclipselink; import javax.persistence.Query; import com.biancama.spring3.model.eclipselink.Employees; public class EmployeesDaoJpaDaoSupportImpl extends EclipseLinkCrudAccessAbstractJPASupport<Integer, Employees> implements EmployeesDao { @Override public int deleteById(Integer id) { Query q = getJpaTemplate().getEntityManager().createQuery( "delete from Employees where employeeId = :id"); q.setParameter("id", id); return q.executeUpdate(); } @Override public Integer getKey(Employees entity) { return entity.getEmployeeId(); } }
I created META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="hr" > <class>com.biancama.spring3.model.eclipselink.Countries</class> <class>com.biancama.spring3.model.eclipselink.Departments</class> <class>com.biancama.spring3.model.eclipselink.EmpDetailsView</class> <class>com.biancama.spring3.model.eclipselink.Employees</class> <class>com.biancama.spring3.model.eclipselink.JobHistory</class> <class>com.biancama.spring3.model.eclipselink.Jobs</class> <class>com.biancama.spring3.model.eclipselink.Locations</class> <class>com.biancama.spring3.model.eclipselink.Regions</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> </persistence-unit> <properties> <property name="eclipselink.weaving" value="false"/> </properties> </persistence>
And finally I injected all the classes with
<?xml version="1.0" encoding="UTF-8"?> <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"> <!-- Tells Spring how to convert JPA-specific exceptions to Spring data exceptions for classes that are annotated with @Repository. --> <bean class= "org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> <!-- Tells Spring to inject the entity manager into DAO classes with a @PersistenceContext annotation placed on a setEntityManager() method. --> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> <bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver" /> </property> --> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> <property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform" /> <property name="generateDdl" value="false" /> <property name="showSql" value="true" /> </bean> </property> <property name="persistenceUnitName" value="hr" /> <property name="persistenceProviderClass" value="org.eclipse.persistence.jpa.PersistenceProvider" /> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <!-- DAO Beans --> <bean id="employeeDao" class="com.biancama.spring3.dao.eclipselink.EmployeesDaoImpl"> <property name="jpaTemplate" ref="jpaTemplate" /> </bean> </beans>
a test unit class could be
package com.biancama.spring3.dao.eclipselink; import static org.junit.Assert.assertTrue; import java.util.List; import javax.annotation.Resource; import org.eclipse.persistence.expressions.ExpressionBuilder; import org.eclipse.persistence.queries.ReadAllQuery; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.biancama.spring3.model.eclipselink.Employees; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:spring3-data-local.xml", "classpath:spring-data-eclipseLinkJPADaoSupport.xml" }) public class EmployeesDaoTestUsingJpaSupport extends AbstractTransactionalJUnit4SpringContextTests { @Resource protected EmployeesDao employeesDao; @Test public void findAll() { ExpressionBuilder builder = new ExpressionBuilder(); ReadAllQuery databaseQuery = new ReadAllQuery(Employees.class, builder); List<Employees> employees = employeesDao .executeDatabaseQuery(databaseQuery); assertTrue(employees != null); assertTrue(employees.size() == 107); } }
Leave a comment