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:  | ### Relevant Articles:  | ||||||
| - [Guide to Hibernate 4 with Spring](http://www.baeldung.com/hibernate-4-spring) | - [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) | - [Hibernate Pagination](http://www.baeldung.com/hibernate-pagination) | ||||||
| - [Sorting with Hibernate](http://www.baeldung.com/hibernate-sort) | - [Sorting with Hibernate](http://www.baeldung.com/hibernate-sort) | ||||||
| - [Stored Procedures with Hibernate](http://www.baeldung.com/stored-procedures-with-hibernate-tutorial) | - [Stored Procedures with Hibernate](http://www.baeldung.com/stored-procedures-with-hibernate-tutorial) | ||||||
|  | |||||||
| @ -6,6 +6,8 @@ | |||||||
| ### Relevant Articles:  | ### Relevant Articles:  | ||||||
| - [A Guide to JPA with Spring](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa) | - [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) | - [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  | ### 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; | package org.baeldung.persistence.model; | ||||||
| 
 | 
 | ||||||
| import org.hibernate.annotations.CacheConcurrencyStrategy; |  | ||||||
| 
 |  | ||||||
| import javax.persistence.*; |  | ||||||
| import java.io.Serializable; | 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 | @Entity | ||||||
| @Cacheable | @Cacheable | ||||||
| @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) | @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 { | public class Foo implements Serializable { | ||||||
| 
 | 
 | ||||||
|     private static final long serialVersionUID = 1L; |     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