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…
Reference in New Issue