Merge pull request #6938 from amit2103/BAEL-14317
[BAEL-14317] - Moved code for DAO with Spring and Hibernate article
This commit is contained in:
		
						commit
						81ba1372d7
					
				| @ -4,7 +4,6 @@ | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
| - [Guide to Hibernate 4 with Spring](http://www.baeldung.com/hibernate-4-spring) | ||||
| - [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) | ||||
| - [Hibernate Pagination](http://www.baeldung.com/hibernate-pagination) | ||||
| - [Sorting with Hibernate](http://www.baeldung.com/hibernate-sort) | ||||
| - [Stored Procedures with Hibernate](http://www.baeldung.com/stored-procedures-with-hibernate-tutorial) | ||||
|  | ||||
| @ -6,6 +6,8 @@ | ||||
| ### Relevant Articles:  | ||||
| - [A Guide to JPA with Spring](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa) | ||||
| - [Bootstrapping Hibernate 5 with Spring](http://www.baeldung.com/hibernate-5-spring) | ||||
| - [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ### Eclipse Config  | ||||
|  | ||||
| @ -0,0 +1,14 @@ | ||||
| package com.baeldung.persistence.dao.common; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| import com.google.common.base.Preconditions; | ||||
| 
 | ||||
| public abstract class AbstractDao<T extends Serializable> implements IOperations<T> { | ||||
| 
 | ||||
|     protected Class<T> clazz; | ||||
| 
 | ||||
|     protected final void setClazz(final Class<T> clazzToSet) { | ||||
|         clazz = Preconditions.checkNotNull(clazzToSet); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,59 @@ | ||||
| package com.baeldung.persistence.dao.common; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.hibernate.Session; | ||||
| import org.hibernate.SessionFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| 
 | ||||
| import com.google.common.base.Preconditions; | ||||
| 
 | ||||
| @SuppressWarnings("unchecked") | ||||
| public abstract class AbstractHibernateDao<T extends Serializable> extends AbstractDao<T> implements IOperations<T> { | ||||
| 
 | ||||
|     @Autowired | ||||
|     protected SessionFactory sessionFactory; | ||||
| 
 | ||||
|     // API | ||||
| 
 | ||||
|     @Override | ||||
|     public T findOne(final long id) { | ||||
|         return (T) getCurrentSession().get(clazz, id); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public List<T> findAll() { | ||||
|         return getCurrentSession().createQuery("from " + clazz.getName()).list(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void create(final T entity) { | ||||
|         Preconditions.checkNotNull(entity); | ||||
|         getCurrentSession().saveOrUpdate(entity); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public T update(final T entity) { | ||||
|         Preconditions.checkNotNull(entity); | ||||
|         return (T) getCurrentSession().merge(entity); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void delete(final T entity) { | ||||
|         Preconditions.checkNotNull(entity); | ||||
|         getCurrentSession().delete(entity); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void deleteById(final long entityId) { | ||||
|         final T entity = findOne(entityId); | ||||
|         Preconditions.checkState(entity != null); | ||||
|         delete(entity); | ||||
|     } | ||||
| 
 | ||||
|     protected Session getCurrentSession() { | ||||
|         return sessionFactory.getCurrentSession(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| package com.baeldung.persistence.dao.common; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public interface IOperations<T extends Serializable> { | ||||
| 
 | ||||
|     T findOne(final long id); | ||||
| 
 | ||||
|     List<T> findAll(); | ||||
| 
 | ||||
|     void create(final T entity); | ||||
| 
 | ||||
|     T update(final T entity); | ||||
| 
 | ||||
|     void delete(final T entity); | ||||
| 
 | ||||
|     void deleteById(final long entityId); | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| package com.baeldung.persistence.dao.impl; | ||||
| 
 | ||||
| import org.baeldung.persistence.dao.IFooDao; | ||||
| import org.baeldung.persistence.model.Foo; | ||||
| import org.springframework.stereotype.Repository; | ||||
| 
 | ||||
| import com.baeldung.persistence.dao.common.AbstractHibernateDao; | ||||
| 
 | ||||
| @Repository | ||||
| public class FooDao extends AbstractHibernateDao<Foo> implements IFooDao { | ||||
| 
 | ||||
|     public FooDao() { | ||||
|         super(); | ||||
| 
 | ||||
|         setClazz(Foo.class); | ||||
|     } | ||||
| 
 | ||||
|     // API | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,118 @@ | ||||
| package org.baeldung.config; | ||||
| 
 | ||||
| import java.util.Properties; | ||||
| 
 | ||||
| import javax.sql.DataSource; | ||||
| 
 | ||||
| import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; | ||||
| import org.baeldung.persistence.dao.IFooDao; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.ComponentScan; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.context.annotation.PropertySource; | ||||
| import org.springframework.core.env.Environment; | ||||
| import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; | ||||
| import org.springframework.data.jpa.repository.config.EnableJpaAuditing; | ||||
| import org.springframework.data.jpa.repository.config.EnableJpaRepositories; | ||||
| import org.springframework.orm.hibernate5.HibernateTransactionManager; | ||||
| import org.springframework.orm.hibernate5.LocalSessionFactoryBean; | ||||
| import org.springframework.orm.jpa.JpaTransactionManager; | ||||
| import org.springframework.orm.jpa.JpaVendorAdapter; | ||||
| import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; | ||||
| import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; | ||||
| import org.springframework.transaction.PlatformTransactionManager; | ||||
| import org.springframework.transaction.annotation.EnableTransactionManagement; | ||||
| 
 | ||||
| import com.baeldung.persistence.dao.impl.FooDao; | ||||
| import com.google.common.base.Preconditions; | ||||
| 
 | ||||
| @Configuration | ||||
| @EnableTransactionManagement | ||||
| @EnableJpaRepositories(basePackages = { "com.baeldung.persistence" }, transactionManagerRef = "jpaTransactionManager") | ||||
| @EnableJpaAuditing | ||||
| @PropertySource({ "classpath:persistence-mysql.properties" }) | ||||
| @ComponentScan({ "com.baeldung.persistence" }) | ||||
| public class PersistenceConfig { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private Environment env; | ||||
| 
 | ||||
|     public PersistenceConfig() { | ||||
|         super(); | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public LocalSessionFactoryBean sessionFactory() { | ||||
|         final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); | ||||
|         sessionFactory.setDataSource(restDataSource()); | ||||
|         sessionFactory.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); | ||||
|         sessionFactory.setHibernateProperties(hibernateProperties()); | ||||
| 
 | ||||
|         return sessionFactory; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public LocalContainerEntityManagerFactoryBean entityManagerFactory() { | ||||
|         final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); | ||||
|         emf.setDataSource(restDataSource()); | ||||
|         emf.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); | ||||
| 
 | ||||
|         final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); | ||||
|         emf.setJpaVendorAdapter(vendorAdapter); | ||||
|         emf.setJpaProperties(hibernateProperties()); | ||||
| 
 | ||||
|         return emf; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public DataSource restDataSource() { | ||||
|         final BasicDataSource dataSource = new BasicDataSource(); | ||||
|         dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); | ||||
|         dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); | ||||
|         dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); | ||||
|         dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); | ||||
| 
 | ||||
|         return dataSource; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public PlatformTransactionManager hibernateTransactionManager() { | ||||
|         final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); | ||||
|         transactionManager.setSessionFactory(sessionFactory().getObject()); | ||||
|         return transactionManager; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public PlatformTransactionManager jpaTransactionManager() { | ||||
|         final JpaTransactionManager transactionManager = new JpaTransactionManager(); | ||||
|         transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); | ||||
|         return transactionManager; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { | ||||
|         return new PersistenceExceptionTranslationPostProcessor(); | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public IFooDao fooHibernateDao() { | ||||
|         return new FooDao(); | ||||
|     } | ||||
| 
 | ||||
|     private final Properties hibernateProperties() { | ||||
|         final Properties hibernateProperties = new Properties(); | ||||
|         hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); | ||||
|         hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); | ||||
| 
 | ||||
|         hibernateProperties.setProperty("hibernate.show_sql", "true"); | ||||
|         // hibernateProperties.setProperty("hibernate.format_sql", "true"); | ||||
|         // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); | ||||
| 
 | ||||
|         // Envers properties | ||||
|         hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix")); | ||||
| 
 | ||||
|         return hibernateProperties; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,13 +1,25 @@ | ||||
| package org.baeldung.persistence.model; | ||||
| 
 | ||||
| import org.hibernate.annotations.CacheConcurrencyStrategy; | ||||
| 
 | ||||
| import javax.persistence.*; | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| import javax.persistence.Cacheable; | ||||
| import javax.persistence.Column; | ||||
| import javax.persistence.Entity; | ||||
| import javax.persistence.FetchType; | ||||
| import javax.persistence.GeneratedValue; | ||||
| import javax.persistence.GenerationType; | ||||
| import javax.persistence.Id; | ||||
| import javax.persistence.JoinColumn; | ||||
| import javax.persistence.ManyToOne; | ||||
| import javax.persistence.NamedNativeQueries; | ||||
| import javax.persistence.NamedNativeQuery; | ||||
| 
 | ||||
| import org.hibernate.annotations.CacheConcurrencyStrategy; | ||||
| 
 | ||||
| @Entity | ||||
| @Cacheable | ||||
| @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) | ||||
| @NamedNativeQueries({ @NamedNativeQuery(name = "callGetAllFoos", query = "CALL GetAllFoos()", resultClass = Foo.class), @NamedNativeQuery(name = "callGetFoosByName", query = "CALL GetFoosByName(:fooName)", resultClass = Foo.class) }) | ||||
| public class Foo implements Serializable { | ||||
| 
 | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
| @ -0,0 +1,20 @@ | ||||
| DELIMITER // | ||||
|     CREATE PROCEDURE GetFoosByName(IN fooName VARCHAR(255)) | ||||
|         LANGUAGE SQL | ||||
|         DETERMINISTIC | ||||
|         SQL SECURITY DEFINER | ||||
|         BEGIN | ||||
|             SELECT * FROM foo WHERE name = fooName; | ||||
|         END // | ||||
| DELIMITER ; | ||||
| 
 | ||||
| 
 | ||||
| DELIMITER // | ||||
|     CREATE PROCEDURE GetAllFoos() | ||||
|         LANGUAGE SQL | ||||
|         DETERMINISTIC | ||||
|         SQL SECURITY DEFINER | ||||
|         BEGIN | ||||
|             SELECT * FROM foo; | ||||
|         END // | ||||
| DELIMITER ; | ||||
| @ -0,0 +1,123 @@ | ||||
| package org.baeldung.persistence.service; | ||||
| 
 | ||||
| import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.baeldung.config.PersistenceConfig; | ||||
| import org.baeldung.persistence.model.Foo; | ||||
| import org.hibernate.Session; | ||||
| import org.hibernate.SessionFactory; | ||||
| import org.hibernate.exception.SQLGrammarException; | ||||
| import org.hibernate.query.NativeQuery; | ||||
| import org.hibernate.query.Query; | ||||
| import org.junit.After; | ||||
| import org.junit.Assume; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||
| import org.springframework.test.context.support.AnnotationConfigContextLoader; | ||||
| 
 | ||||
| @RunWith(SpringJUnit4ClassRunner.class) | ||||
| @ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) | ||||
| public class FooStoredProceduresLiveTest { | ||||
| 
 | ||||
|     private static final Logger LOGGER = LoggerFactory.getLogger(FooStoredProceduresLiveTest.class); | ||||
| 
 | ||||
|     @Autowired | ||||
|     private SessionFactory sessionFactory; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private FooService fooService; | ||||
| 
 | ||||
|     private Session session; | ||||
| 
 | ||||
|     @Before | ||||
|     public final void before() { | ||||
|         session = sessionFactory.openSession(); | ||||
|         Assume.assumeTrue(getAllFoosExists()); | ||||
|         Assume.assumeTrue(getFoosByNameExists()); | ||||
|     } | ||||
| 
 | ||||
|     private boolean getFoosByNameExists() { | ||||
|         try { | ||||
|             @SuppressWarnings("unchecked") | ||||
|             NativeQuery<Foo> sqlQuery = session.createSQLQuery("CALL GetAllFoos()").addEntity(Foo.class); | ||||
|             sqlQuery.list(); | ||||
|             return true; | ||||
|         } catch (SQLGrammarException e) { | ||||
|             LOGGER.error("WARNING : GetFoosByName() Procedure is may be missing ", e); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private boolean getAllFoosExists() { | ||||
|         try { | ||||
|             @SuppressWarnings("unchecked") | ||||
|             NativeQuery<Foo> sqlQuery = session.createSQLQuery("CALL GetAllFoos()").addEntity(Foo.class); | ||||
|             sqlQuery.list(); | ||||
|             return true; | ||||
|         } catch (SQLGrammarException e) { | ||||
|             LOGGER.error("WARNING : GetAllFoos() Procedure is may be missing ", e); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @After | ||||
|     public final void after() { | ||||
|         session.close(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public final void getAllFoosUsingStoredProcedures() { | ||||
| 
 | ||||
|         fooService.create(new Foo(randomAlphabetic(6))); | ||||
| 
 | ||||
|         // Stored procedure getAllFoos using createSQLQuery | ||||
|         @SuppressWarnings("unchecked") | ||||
|         NativeQuery<Foo> sqlQuery = session.createSQLQuery("CALL GetAllFoos()").addEntity(Foo.class); | ||||
|         List<Foo> allFoos = sqlQuery.list(); | ||||
|         for (Foo foo : allFoos) { | ||||
|             LOGGER.info("getAllFoos() SQL Query result : {}", foo.getName()); | ||||
|         } | ||||
|         assertEquals(allFoos.size(), fooService.findAll().size()); | ||||
| 
 | ||||
|         // Stored procedure getAllFoos using a Named Query | ||||
|         @SuppressWarnings("unchecked") | ||||
|         Query<Foo> namedQuery = session.getNamedQuery("callGetAllFoos"); | ||||
|         List<Foo> allFoos2 = namedQuery.list(); | ||||
|         for (Foo foo : allFoos2) { | ||||
|             LOGGER.info("getAllFoos() NamedQuery result : {}", foo.getName()); | ||||
|         } | ||||
|         assertEquals(allFoos2.size(), fooService.findAll().size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public final void getFoosByNameUsingStoredProcedures() { | ||||
| 
 | ||||
|         fooService.create(new Foo("NewFooName")); | ||||
| 
 | ||||
|         // Stored procedure getFoosByName using createSQLQuery() | ||||
|         @SuppressWarnings("unchecked") | ||||
|         Query<Foo> sqlQuery = session.createSQLQuery("CALL GetFoosByName(:fooName)").addEntity(Foo.class).setParameter("fooName", "NewFooName"); | ||||
|         List<Foo> allFoosByName = sqlQuery.list(); | ||||
|         for (Foo foo : allFoosByName) { | ||||
|             LOGGER.info("getFoosByName() using SQL Query : found => {}", foo.toString()); | ||||
|         } | ||||
| 
 | ||||
|         // Stored procedure getFoosByName using getNamedQuery() | ||||
|         @SuppressWarnings("unchecked") | ||||
|         Query<Foo> namedQuery = session.getNamedQuery("callGetFoosByName").setParameter("fooName", "NewFooName"); | ||||
|         List<Foo> allFoosByName2 = namedQuery.list(); | ||||
|         for (Foo foo : allFoosByName2) { | ||||
|             LOGGER.info("getFoosByName() using Native Query : found => {}", foo.toString()); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user