Track Sheet
Last Updated on 20211217
Application Overview Excel
Track Sheet
Last Updated on 20211217
Application Overview Excel
In the Spring Container the underlying persistence unit(oracle, mysql) used can be conveyed in three ways
Using Dialect in Spring(or)application.xml
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> .... </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="emf"/> <property name="jpaDialect" ref="jpaDialect"/> </bean>
We are telling ‘Spring’ to configure a transactionManager whose properties are entityManagerFactory and jpaDialect. Since these properties have to be specific to hibernate these are set according. The entityManagerFactory and jpaDialect are now set specifically to hibernate (or Vendor).
Dialect and Vendor Adapter works together
Notes:
Using Vendor in Spring(or)application.xml
<property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property>
the VendorAdapter is injected in to transactionManager along with entityManager
Since you have provided the class as class=”org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter”/>, this allows Spring to plug in vendor-specific behavior into Spring’s EntityManagerFactory creators and it serves as single configuration point for all vendor-specific properties.It’s a custom implementation of spring’s own JpaVendorAdapter.
The reason it is so is the underlying database differs from application to application based on the needs and the underlying persistence unit which the developer would like to use I.E MySQL, Oracle.
Using Provider persistence-context.xml
The
Note:
Application works just by configuring persistence and provider because the vendor adapter is automatically passed by the persistence provided i.e. HibernatePersistence via the getPersistenceProvider in JpaVendorAdapter.
Provider + JpaVendorAdapter(Used getPersistenceProvider to get underlying Persistence technology in our case hibernate) -> Works
Dialect + JpaVendorAdapter -> Works
Provider + Dialect -> Doesn’t Works
Difference between configuring data source in persistence.xml and spring (or) application-context.xml files
persistence-context.xml
<persistence-unit name="LocalDB" transaction-type="RESOURCE_LOCAL"> <class>domain.User</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost"/> <property name="hibernate.hbm2ddl.auto" value="create"/> <property name="hibernate.c3p0.min_size" value="5"/> .... <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> </properties> </persistence-unit>
application-context.xml
<bean id="domainEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="JiraManager"/> <property name="dataSource" ref="domainDataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="generateDdl" value="false"/> <property name="showSql" value="false"/> <property name="databasePlatform" value="${hibernate.dialect}"/> </bean> </property> </bean> <bean id="domainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${db.driver}" /> <property name="jdbcUrl" value="${datasource.url}" /> <property name="user" value="${datasource.username}" /> <property name="password" value="${datasource.password}" /> <property name="initialPoolSize" value="5"/> <property name="minPoolSize" value="5"/> ..... </bean>
If you are using persistence.xml you’re creating your own connection pool and do not profit from the existing connection pool in the container. Thus even if you configured your container to, say, a max of 20 simultaneous connections to the database, you can’t guarantee this max as this new connection pool is not restrained by your configuration. Also, you don’t profit from any monitoring tools your container provides you.
If you are using spring (or) application.xml
If you’re also creating your own connection pool, with the same disadvantages as above. However, you can isolate the definition of this spring bean and only use it in test runs.Your best bet is to look up the container’s connection pool via JNDI. Then you are sure to respect the data source configurations from the container.
application-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="mugil.org.*" /> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource" p:persistenceUnitName="simple-jpa"> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/MUSIC_STORE"/> <property name="username" value="music_store"/> <property name="password" value="music_store"/> </bean> </beans>
Dissection of application-context.xml
<context:component-scan base-package="mugil.org.*" />
Note:
When we use component-scan in the app-context.xml, it’s not necessary to use annotation-config again.Even if both the tags are specified, it’s not a problem because, the spring container would take care of running the process only once.
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/MUSIC_STORE"/> <property name="username" value="music_store"/> <property name="password" value="music_store"/> </bean>
persistence-context.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.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_2_0.xsd"> <persistence-unit name="simple-jpa" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>mugil.pojo.MusicDetails</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.max_fetch_depth" value="3"/> </properties> </persistence-unit> </persistence>
Dissection of persistence-context.xml
Other Java Codes
DaoInterface.java
public interface IMusicStoreDao { public List getMusicList(); }
DaoImplementation.java
@Service(value = "MusicCollections") @Repository(value = "MusicCollections") @Transactional public class MusicStoreDaoImpl implements IMusicStoreDao{ @PersistenceContext(unitName = "simple-jpa") private EntityManager entityManager; @Override public List getMusicList(){ List musicDetailsList= entityManager.createQuery("select c from MusicDetails c").getResultList(); return musicDetailsList; } }
Executer.java
public class Executer { public static void main(String[] args){ ApplicationContext applicationContext=new ClassPathXmlApplicationContext("META-INF/app-context.xml"); IMusicStoreDao musicStoreDao=(IMusicStoreDao) applicationContext.getBean("MusicCollections"); System.out.println("MusicList: \n"+musicStoreDao.getMusicList()); } }
Reference:
Spring and JPA
Sketch Notes Samples
In a Application the persistence unit used to store the data may vary.Accessing data varies depending on the source of the data. Access to persistent data varies greatly depending on the type of storage (database, flat files, xml files, and so on) and it even differs from its implementation (for example different SQL-dialects).
The advantage of the DAO layer is that if you need to change the underlying persistence mechanism you only have to change the DAO layer, and not all the places in the domain logic where the DAO layer is used from. The DAO layer usually consists of a smaller set of classes, than the number of domain logic classes that uses it.
Abstract and encapsulate all access to the data and provide an interface. This is called the Data Access Object pattern. In a nutshell, the DAO “knows” which data source (that could be a database, a flat file or even a WebService) to connect to and is specific for this data source (e.g. a OracleDAO might use oracle-specific data types, a WebServiceDAO might parse the incoming and outgoing message etc.)
BookDAO.java
public interface BookDAO { public void saveBook(Book b); public Book loadBook(String isbn); }
DBBookDAO.java
public class DBBookDAO implements BookDAO { private PreparedStatement saveStmt; private PreparedStatement loadStmt; public DBBookDAO(String url, String user, String pw) { Connection con = DriverManager.getConnection(url, user, pw); saveStmt = con.prepareStatement("INSERT INTO books(isbn, title, author) " +"VALUES (?, ?, ?)"); loadStmt = con.prepareStatement("SELECT isbn, title, author FROM books " +"WHERE isbn = ?"); } public Book loadBook(String isbn) { Book b = new Book(); loadStmt.setString(1, isbn); ResultSet result = loadStmt.executeQuery(); if (!result.next()) return null; b.setIsbn(result.getString("isbn")); b.setTitle(result.getString("title")); b.setAuthor(result.getString("author")); return b; } public void saveBook(Book b) { saveStmt.setString(1, b.getIsbn()); saveStmt.setString(2, b.getTitle()); saveStmt.setString(3, b.getAuthor()); saveStmt.executeUpdate(); } }
FileBookDAO.java
public class FileBookDAO implements BookDAO { private String basePath; public FileBookDAO(String basePath) { this.basePath = basePath; } public Book loadBook(String isbn) { FileReader fr = new FileReader(basePath + isbn); BufferedReader br = new BufferedReader(fr); Book b = new Book(); String rIsbn = br.readLine(); String rTitle = br.readLine(); String rAuthor = br.readLine(); if (rIsbn.startsWith("ISBN: ")) { b.setIsbn(rIsbn.substring("ISBN: ".length())); } else { return null; } if (rTitle.startsWith("TITLE: ")) { b.setTitle(rTitle.substring("TITLE: ".length())); } else { return null; } if (rAuthor.startsWith("AUTHOR: ")) { b.setAuthor(rAuthor.substring("AUTHOR: ".length())); } else { return null; } return b; } public void saveBook(Book b) { FileWriter fw = new FileWriter(basePath + b.getIsbn() + ".book"); fw.write("ISBN: " + b.getIsbn()); fw.write("TITLE: " + b.getTitle()); fw.write("AUTHOR: " + b.getAuthor()); fw.close(); } }
org.springframework.orm.hibernate3.support.HibernateDaoSupport | org.springframework.orm.hibernate3.HibernateTemplate | org.hibernate.SessionFactory
import java.util.Collection; public interface StudentDao { public Student getStudent(long id); public Collection getAllStudents(); public Collection findStudents(String lastName); public void saveStudent(Student std); public void removeStudent(Student std); }
Using DAOSupport Object
StudentDao.java
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import java.util.Collection; public class HibernateStudentDao extends HibernateDaoSupport implements StudentDao { public Student getStudent(long id) { return (Student) getHibernateTemplate().get(Student.class, new Long(id)); } public Collection getAllStudents() { return getHibernateTemplate().find("from Student std order by std.lastName, std.firstName"); } public Collection findStudents(String lastName) { return getHibernateTemplate().find("from Student std where std.lastName like ?", lastName + "%"); } public void saveStudent(Student std) { getHibernateTemplate().saveOrUpdate(std); } public void removeStudent(Student std) { getHibernateTemplate().delete(std); } }
import org.springframework.orm.hibernate3.HibernateTemplate; import java.util.Collection; public class HibernateStudentDao implements StudentDao { HibernateTemplate hibernateTemplate; public Student getStudent(long id) { return (Student) getHibernateTemplate().get(Student.class, new Long(id)); } public Collection getAllStudents() { return getHibernateTemplate().find("from Student std order by std.lastName, std.firstName"); } public Collection findStudents(String lastName) { return getHibernateTemplate().find("from Student std where std.lastName like "+ lastName + "%"); } public void saveStudent(Student std) { getHibernateTemplate().saveOrUpdate(std); } public void removeStudent(Student std) { getHibernateTemplate().delete(std); } public HibernateTemplate getHibernateTemplate() { return hibernateTemplate; } public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; } }
Using SessionFactory Object
import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.springframework.orm.hibernate3.SessionFactoryUtils; import java.util.Collection; public class HibernateStudentDao implements StudentDao { SessionFactory sessionFactory; public Student getStudent(long id) { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { return (Student) session.get(Student.class, new Long(id)); } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public Collection getAllStudents() { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { Query query = session.createQuery("from Student std order by std.lastName, std.firstName"); Collection allStudents = query.list(); return allStudents; } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public Collection getGraduatedStudents() { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { Query query = session.createQuery("from Student std where std.status=1"); Collection graduatedStudents = query.list(); return graduatedStudents; } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public Collection findStudents(String lastName) { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { Query query = session.createQuery("from Student std where std.lastName like ?"); query.setString(1, lastName + "%"); Collection students = query.list(); return students; } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public void saveStudent(Student std) { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { session.save(std); } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public void removeStudent(Student std) { Session session = SessionFactoryUtils.getSession(this.sessionFactory, true); try { session.delete(std); } catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } finally { SessionFactoryUtils.closeSession(session); } } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } }
Using HibernateCallback
public void saveStudent(Student std) { HibernateCallback callback = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { return session.saveOrUpdate(std); } }; getHibernateTemplate().execute(callback); }
What is Template Pattern?
Template pattern, an abstract class exposes a ways to execute its methods. The subclasses can override the method implementation as per need but the invocation is to be in the same way as defined by an abstract class
When to use Template Pattern?
What is BeanFactory?
The BeanFactory is the actual container which instantiates, configures, and manages a number of beans.Let have a look at how spring works
How it Works
BeanFactory is represented by org.springframework.beans.factory.BeanFactory interface.It is the main and the basic way to access the Spring container.Other ways to access the spring container such as ApplicationContext,ListableBeanFactory, ConfigurableBeanFactory etc. are built upon this BeanFactory interface.
BeanFactory interface defines basic functionality for the Spring Container like
Note that BeanFactory does not create the objects of beans immediately when it loads the configuration for beans from configuration source.Only bean definitions and their property descriptions are loaded. Beans themselves are instantiated and their properties are set only when they are requested such as by getBean() method.
Different BeanFactory Implementations:
XmlBeanFactory using Constructor:
Resource res = new FileSystemResource("c:/beansconfig.xml"); BeanFactory bfObj = new XmlBeanFactory(res); MyBean beanObj= (MyBean) bfObj.getBean("mybean");
ClassPathResource resorce = new ClassPathResource ("beansconfig.xml"); BeanFactory factory = new XmlBeanFactory(resource);
ClassPathXmlApplicationContext:
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] {"applicationContext.xml", "applicationContext-part2.xml"}); //an ApplicationContext is also a BeanFactory. BeanFactory factory = (BeanFactory) appContext;
Note BeanFactory is not recomended for use in latest Spring versions. It is there only for backward compatability. ApplicationContext is preferred over this because ApplicationContext provides more advance level features which makes an application enterprise level application.
This is caused by setting something too large on a 32-bit HotSpot vm, for example:If you have running the x86 JVM instead of the 64 bit you may end up with this issue
While running Maven Sure fire plugin you may endup with this problem mostly when you are using 32 bit version of Java
set "JAVA_OPTS=-Xms512m -Xmx512m -XX:MaxPermSize=512m
The MaxPermSize allowed is 512m, but it still throws error when you try to run a build setting to max of 512m.
Set MaxPermSize less than 500m
Solution
set "JAVA_OPTS=-Xms512m -Xmx400m -XX:MaxPermSize=512m
This may also happen if maven is not using the right JVM if more that one JVM is installed in the system or set MAVEN_OPTS = -Xmx512m -XX:MaxPermSize=128m