Merge pull request #6938 from amit2103/BAEL-14317

[BAEL-14317] - Moved code for DAO with Spring and Hibernate article
This commit is contained in:
Loredana Crusoveanu 2019-05-11 13:52:41 +03:00 committed by GitHub
commit 81ba1372d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 391 additions and 4 deletions

View File

@ -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)

View File

@ -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

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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 ;

View File

@ -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());
}
}
}