JPA interview questions and answers and high level overview - part 1
A. The process of mapping Java objects to database tables and vice versa is called "Object-relational mapping" (ORM). The Java Persistence API provides Java developers with an object/relational mapping (ORM) facility for managing relational data in Java applications. JPA is a specification and several implementations are available like EJB, JDO, Hibernate, and Toplink. Via JPA the developer can map, store, update and retrieve data from relational databases to Java objects and vice versa.
Q. What is the difference between hibernate.cfg.xml and persistence.xml?
A. If you are using Hibernate's proprietary API, you'll need the hibernate.cfg.xml. If you are using JPA i.e. Hibernate EntityManager, you'll need the persistence.xml. You will not need both as you will be using either Hibernate proprietary API or JPA. However, if you had used Hibernate Proprietary API using hibernate.cfg.xml with hbm.xml mapping files, and now wanted to start using JPA, you can reuse the existing configuration files by referencing the hibernate.cfg.xml in the persistence.xml in the hibernate.ejb.cfgfile property and reuse the existing hbm.xml files. In a long run, migrate hbm.xml files to JPA annotations.
Q. What is an EntityManagerFactory and a Persistence unit?
A. The EntityManager is created by the EntitiyManagerFactory which is configured by the persistence unit. The persistence unit is described via the file "persistence.xml" in the directory META-INF in the source folder. It defines a set of entities which are logically connected and the connection properties as shown below via an example.
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.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_1_0.xsd"> <persistence-unit name="myapp-server" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <!-- import other mapping files if any --> <mapping-file>META-INF/myApp2.xml</mapping-file> <class>com.mycompany.myapp.Person</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> <property name="javax.persistence.jdbc.url" value="jdbc:derby:/home/myapp/databases/simpleDb;create=true" /> <property name="javax.persistence.jdbc.user" value="test" /> <property name="javax.persistence.jdbc.password" value="test" /> <!-- force Hibernate to use a singleton of Ehcache CacheManager --> <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" /> <property name="hibernate.cache.use_second_level_cache" value="true" /> <property name="hibernate.cache.use_query_cache" value="true" /> <property name="net.sf.ehcache.configurationResourceName" value="ehcache.xml" /> </properties> </persistence-unit> </persistence>
Usually, JPA defines a persistence unit through the META-INF/persistence.xml file. Starting with Spring 3.1, this XML file is no longer necessary – the LocalContainerEntityManagerFactoryBean now supports a ‘packagesToScan’ property where the packages to scan for @Entity classes can be specified. The snippet below shows how you can bootstrap with or without persistence.xml.
package com.mycompany.app.config; import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; import org.springframework.orm.hibernate4.HibernateExceptionTranslator; 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; @Configuration @PropertySource(value = {"classpath:/common/jpa.properties" }) @EnableTransactionManagement public class JpaConfig { @Value("${my_app_common_jpa_showSql:false}") private Boolean showSql; @Value("${my_app_common_jpa_hibernateDialect}") private String hibernateDialect; @Value("${my_app_common_jpa_generateStatistics:false}") private Boolean generateStatistics; @Value("${my_app_common_jpa_generateDdl:false}") private Boolean generateDdl; @Value("${my_app_common_jpa_databasePlatform}") private String databasePlatform; @Resource(name = "myAppDataSource") private DataSource dataSource; private static Logger LOGGER = LoggerFactory.getLogger(JpaConfig.class); @Bean public Map<String, Object> jpaProperties() { LOGGER.debug("jpaProperties hibernateDialect=" + hibernateDialect); Map<String, Object> props = new HashMap<String, Object>(); props.put("hibernate.dialect", hibernateDialect); props.put("hibernate.generate_statistics", generateStatistics); return props; } @Bean public JpaVendorAdapter jpaVendorAdapter() { LOGGER.debug("jpaProperties databasePlatform=" + databasePlatform); HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter(); hibernateJpaVendorAdapter.setShowSql(showSql); hibernateJpaVendorAdapter.setGenerateDdl(generateDdl); hibernateJpaVendorAdapter.setDatabasePlatform(databasePlatform); return hibernateJpaVendorAdapter; } @Bean public PlatformTransactionManager transactionManager() { return new JpaTransactionManager(entityManagerFactory()); } @Bean public EntityManagerFactory entityManagerFactory() { LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean(); lef.setDataSource(dataSource); lef.setJpaPropertyMap(this.jpaProperties()); lef.setJpaVendorAdapter(this.jpaVendorAdapter()); lef.setPersistenceXmlLocation("META-INF/persistence.xml"); //alternative without persistence.xml from Spring 3.1 //lef.setPackagesToScan("com.mycompany.myapp"); lef.afterPropertiesSet(); return lef.getObject(); } @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); } @Bean public HibernateExceptionTranslator hibernateExceptionTranslator() { return new HibernateExceptionTranslator(); } }
The jpa.properties can be defined as shown below.
# properties for JPA my_app_common_jpa_showSql=false my_app_common_jpa_generateDdl=false my_app_common_jpa_databasePlatform=SYBASE my_app_common_jpa_hibernateDialect=org.hibernate.dialect.SybaseASE15Dialect my_app_common_jpa_generateStatistics=true my_app_common_aesJndiName=java:comp/env/jdbc/my_db
The configuration shown above is Java based config, and if you want to use a Spring xml file based config, it will look like
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="org.rest" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="${my_app_common_jpa_showSql}" /> <property name="generateDdl" value="${my_app_common_jpa_generateDdl}" /> <property name="databasePlatform" value="${my_app_common_jpa_hibernateDialect}" /> </bean> </property> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${driverClassName}" /> <property name="url" value="${url}" /> <property name="username" value="${user}" /> <property name="password" value="${password}" /> </bean> <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="myEmf" /> </bean> <tx:annotation-driven transaction-manager="txManager" />
Labels: Hibernate, Hibernate Tutorial, JPA
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home