4 Spring JPA Hibernate
4 Spring JPA Hibernate
Agenda
Persistence
Spring Persistence
Spring JDBC Spring Hibernate Spring JPA Spring iBatis
just tedious
redundant...
repeating code
Focus
DRY - Dont Repeat Yourself Testable Concise Stop forcing all the checked exceptions
JDBCTemplate
Remaining Challenges?
Testability...
10
Lazy vs. Eager decisions As the project grows the ORM pain grows
11
Hibernate was the clear winner in the ORM race... However it wasnt a standard...
12
13
14
Spring HibernateDaoSupport
15
Spring HibernateTransactionManager
16
Hibernate Consequences
XML focused
17
JPA
18
JPA Benefits
Standards-Based No Descriptors necessary Annotated POJOs Detached Object Support Reduce Overhead of DTO / VO Improve Testability
JPA - Specification
Packaging Entities Entity Operations Queries Metadata Life-cycle Model Callbacks
Persistence.xml
In the classpath under the META-INF directory.
<persistence-unit name="unit1" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.hbm2ddl.auto" value="create"/> <property name="hibernate.ejb.autodetection" value="class"/> <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost:1234/employee"/> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> <property name="hibernate.connection.username" value="sa"/> <property name="hibernate.connection.password" value=""/> </properties> </persistence-unit> </persistence>
Entity Requirements
Must be annotated an Entity Public or Protected No-arg Constructor Must not be final
Persistent Fields
Primitives and Strings
@Entity(access=FIELD) public class Customer { @Id(generate=AUTO) Long id; @Version protected int version; @ManyToOne Address address; @Basic String description; @OneToMany(targetEntity=com.acme.Order.class, mappedBy="customer") Collection orders = new Vector(); @ManyToMany(mappedBy="customers") Set<DeliveryService> serviceOptions = new HashSet(); public Customer() {} public Collection getOrders() { return orders; } public Set<DeliveryService> getServiceOptions() {
25
Entity Manager void persist(Object entity); <T> T merge(T entity); void remove(Object entity); <T> T find(Class<T> entityClass, Object primaryKey); <T> T getReference(Class<T> entityClass, Object primaryKey); void flush(); void refresh(Object entity); boolean contains(Object entity); void close(); boolean isOpen(); EntityTransaction getTransaction();
Acquiring a Manager
OR
@PersistenceContext(unitName="order") EntityManager em;
JPA Query
JPQL Example:
public List<Session> findSessionByCatagory(String name) { return entityManager.createQuery(
"from Session session where session.catagory.name=:name")
.setParameter("name", name).getResultList(); }
JPA Challenges
2 Programming Models
30
Spring 2.x
Persistence.xml Persistence
EntityManager Factory
JpaTemplate Query
persist()
EntityManager
EntityManagerFactoryBean
Transaction
LocalEntityManagerFactoryBean
Provides resource bootstrapping for non-jndi lookups
Not preferred approach Similar to HibernateDaoSupport Requires Spring Configuration of the EntityManager
Pure JPA Approach
Preferred approach No spring references necessary in the code with the exception of @Transactional
34
Approach 1: JpaDaoSupport
JpaDaoSupport with JpaTemplate to simplify common code very familiar to hibernate developers
Consequences:
import of spring framework not exactly POJO requires spring configuration of entitymanager
36
EntityManager
import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.transaction.annotation.Transactional; public class ConferenceDAOImpl implements ConferenceDAO { @PersistenceContext private EntityManager entityManager;
</beans>
40
No PU No Problem
The LocalContainerEntityManagerFactoryBean can be
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="true"/> <property name="generateDdl" value="true"/> <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect"/> </bean> </property> </bean>
Transactions
XML Configuration
<tx:annotation-driven />
Annotation
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) Public void doSomething() { ** transaction manger bean id must be transactionManger or configured with the xml configuration above.
AbstractJpaTests Benefits
getConfigLocations ()
Separates test from production configuration Allows for multiple configurations
Demo
JPA with Spring
References
http://www.springframework.org/ http://java.sun.com/developer/technicalArticles/J2EE/jpa http://www.hibernate.org/hib_docs/annotations/
reference/en/html/entity.html
Questions