J2EE Lecture 8: Hibernate Dr. Ming Qiu Xiamen University Software School mingqiu@xmu.edu.cn
8.1 Domain Models and metaData Hibernate in Action, Chap 3 8.1 Domain Models and metaData CaveatEmptor Online Auction Application http://caveatemptor.hibernate.org
8.1 Domain Models and metaData EJB in Action, Chap 7 8.1 Domain Models and metaData A conceptual image of the problem your system is trying to solve. made up of the concepts and the relationships or associations between them
8.1 Domain Models and metaData EJB in Action, Chap 7 8.1 Domain Models and metaData
8.1 Domain Models and metaData EJB in Action, Chap 7 8.1 Domain Models and metaData
8.1 Domain Models and metaData EJB in Action, Chap 7 8.1 Domain Models and metaData
8.1 Domain Models and metaData Hibernate in Action, Chap 3 8.1 Domain Models and metaData
8.2 Object-Relational Mapping Mastering EJB3.0, Chap 6 8.2 Object-Relational Mapping Two ways to persist object in Java Use Java’s serialization API. Use traditional relational database management system. Object-Relational Mapping Convert and unconvert the in memory object to relational data
8.2 Object-Relational Mapping Mastering EJB3.0, Chap 6 8.2 Object-Relational Mapping
8.2 Object-Relational Mapping EJB in Action, Chap 7 8.2 Object-Relational Mapping
8.2 Object-Relational Mapping Mastering EJB3.0, Chap 6 8.2 Object-Relational Mapping Mapping objects to relational data can be done in two ways Handcraft the mapping in your code Use an object-relational mapping product ORACLE TopLink Hibernate The Java Persistence specification defines a standardized object-relational mapping and required compliant products to implement it.
8.2 Object-Relational Mapping Mastering EJB3.0, Chap 6 8.2 Object-Relational Mapping Java Persistence API (JPA) A separate specification document Available for EJB3.0 Provides a POJO programing model for persistent object Provides a standard object-relational mapping Not tied to the Java EE container Defines a service provider interface
8.2 Object-Relational Mapping Hibernate in Action, Chap 3 8.2 Object-Relational Mapping Writing POJOs and persistent entity classes Hibernate doesn’t require that any special super classes or interfaces be inherited or implemented by persistent classes. Persistent classes can be reused outside the context of persistence, In a system with transparent persistence, objects aren’t aware of the underlying data store;
8.2 Object-Relational Mapping Mastering EJB3.0, Chap 6 8.2 Object-Relational Mapping Persistent Provider To transfer entity information back and forth between the Java object and database. Worries about the proper time to load and store the data Automatically figures out when each of your instances needs to be refreshed Define a Persistent Provider SPI In Java EE, the container implements the SPI
8.2 Object-Relational Mapping Mastering EJB3.0, Chap 6 8.2 Object-Relational Mapping Entity Class Is a POJO marked with @Entity Maps to a data definition in a relational database Has metadata annotation or XML deployment descriptor Must declare a primary key Access to entity’s persistent state can be by direct field access or by set and get method Can expose business methods
Hibernate in Action, Chap 3
8.2 Object-Relational Mapping Hibernate in Action, Chap 3 8.2 Object-Relational Mapping public class Category { private String name; private Category parentCategory; private Set childCategories = new HashSet(); public Category() { } ... }
8.2 Object-Relational Mapping Hibernate in Action, Chap 3 8.2 Object-Relational Mapping public class Category { ... private Set items = new HashSet(); public Set getItems() { return items; } public void setItems(Set items) { this.items = items;
private String description; ... Hibernate in Action, Chap 3 public class Item { private String name; private String description; ... private Set categories = new HashSet(); public Set getCategories() { return categories; } private void setCategories(Set categories) { this.categories = categories; public void addCategory(Category category) { if (category == null) throw new IllegalArgumentException("Null category"); category.getItems().add(this); categories.add(category);
Hibernate in Action, Chap 3
8.2 Object-Relational Mapping Hibernate in Action, Chap 3 8.2 Object-Relational Mapping package auction.model; import javax.persistence.*; @Entity @Table(name = "ITEM") @org.hibernate.annotations.BatchSize(size = 10) @org.hibernate.annotations.DiscriminatorFormula( "case when ITEM_IS_SPECIAL is not null then A else B end" ) public class Item { ... } package auction.model; import javax.persistence.*; @Entity @Table(name = "ITEM") public class Item { ... }
8.2 Object-Relational Mapping Hibernate in Action, Chap 4 8.2 Object-Relational Mapping Mapping Identifier Property @Entity @Table(name="CATEGORY") public class Category { private Long id; ... @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "CATEGORY_ID") public Long getId() { return this.id; } private void setId(Long id) { this.id = id;
8.2 Object-Relational Mapping Hibernate in Action, Chap 4 8.2 Object-Relational Mapping Class Mapping Options Making an entity immutable No setter methods @Entity @org.hibernate.annotations.Entity(mutable = false) @org.hibernate.annotations.AccessType("field") public class Bid { ...
Hibernate in Action, Chap 2 8.3 Working with Objects
8.3 Working with Objects Top down Hibernate in Action, Chap 2 8.3 Working with Objects Top down Start with an existing domain model, its implementation in Java, and (ideally) complete freedom with respect to the database schema. Create mapping metadata— either with XML files or by annotating the Java source Let Hibernate’s hbm2ddl tool generate the database schema
8.3 Working with Objects Bottom up Hibernate in Action, Chap 2 8.3 Working with Objects Bottom up use the reverse-engineering tools to extract metadata from the database. hbm2hbmxml – XML mapping files Hbm2java – Java persistent classes (including annotation)
Hibernate in Action, Chap 9 8.3 Working with Objects
Hibernate in Action, Chap 9 8.3 Working with Objects
8.3 Working with Objects The Hibernate interfaces Hibernate in Action, Chap 9 8.3 Working with Objects The Hibernate interfaces Storing and loading objects
8.3 Working with Objects Retrieving a persistent object Hibernate in Action, Chap 9 8.3 Working with Objects Retrieving a persistent object
8.3 Working with Objects Modifying a persistent object Hibernate in Action, Chap 9 8.3 Working with Objects Modifying a persistent object
8.3 Working with Objects Making a persistent object transient Hibernate in Action, Chap 9 8.3 Working with Objects Making a persistent object transient
8.3 Working with Objects Reattaching a modified detached instance Hibernate in Action, Chap 9 8.3 Working with Objects Reattaching a modified detached instance
8.3 Working with Objects Reattaching an unmodified detached instance Hibernate in Action, Chap 9 8.3 Working with Objects Reattaching an unmodified detached instance
8.3 Working with Objects EntityManager EJB in Action, Chap 9 8.3 Working with Objects EntityManager the bridge between the OO and relational worlds
8.3 Working with Objects What does the EntityManager do? EJB in Action, Chap 9 8.3 Working with Objects What does the EntityManager do? Providing explicit SQL-like CRUD operations Keep entities synched with the database automatically as long as they are within the EntityManager’s reach
EJB in Action, Chap 9 8.3 Working with Objects The complete EntityManager API provides methods for three different kinds of operations Entity life-cycle management Database synchronization operation Entity lookup and queries
EJB in Action, Chap 9 8.3 Working with Objects
EJB in Action, Chap 9
EJB in Action, Chap 9 8.3 Working with Objects Entity Life Cycle
8.3 Working with Objects remove() merge() EJB in Action, Chap 9 8.3 Working with Objects remove() The in-memory entity instance is not actually going to be destroyed. The actual deletion happens when the transaction is committed. Calling remove() on a detached entity will raise an illegalArgumentException merge() Allows you to bring detached entities back to the persistence context.
8.3 Working with Objects Detached Entities EJB in Action, Chap 9 8.3 Working with Objects Detached Entities Entities that is no longer managed by the EntityManager No guarantee that the state of the entity is in synch with the database The usual way entities become detached Pass them to the web tier Go out of the EntityManager context’s scope Through cloning or serialization EntityManager keeps track of entities through Java object references Call the clear/remove method of EntityManager clear method forces all entities in the persistence context to be detached.
EJB in Action, Chap 9 8.3 Working with Objects
EJB in Action, Chap 9
EJB in Action, Chap 9 8.3 Working with Objects
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
8.4 Inheritance Three mapping strategies Mastering EJB3.0, Chap 9 8.4 Inheritance Three mapping strategies Single table per class hierarchy Separate table per subclass Single table per concrete entity class
8.4 Inheritance Single Table per Class Hierarchy Mastering EJB3.0, Chap 9 8.4 Inheritance Single Table per Class Hierarchy A discriminator column is used to distinguish between subclasses Advantage Be efficient and support polymorphism Disadvantage Have a column representing every field of every class in hierarchy
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
8.4 Inheritance Table generated from annotation Mastering EJB3.0, Chap 9 8.4 Inheritance Table generated from annotation
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance Separate Table per Subclass
Mastering EJB3.0, Chap 9 8.4 Inheritance
Mastering EJB3.0, Chap 9 8.4 Inheritance
8.4 Inheritance Query executed behind the scenes Mastering EJB3.0, Chap 9 8.4 Inheritance Query executed behind the scenes
8.4 Inheritance Disadvantage Mastering EJB3.0, Chap 9 8.4 Inheritance Disadvantage Table joins must be performed in order to get at all of the properties of subclasses Performance is low when the class hierarchy is deep
8.4 Inheritance Polymorphism with Entity Mastering EJB3.0, Chap 9 8.4 Inheritance Polymorphism with Entity The same way we are used to with regular Java This is done through JPQL Query
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9 8.4 Inheritance
8.5 Relationships Relationship Types One-to-one One-to-many Mastering EJB3.0, Chap 9 8.5 Relationships Relationship Types One-to-one One-to-many Many-to-one Many-to-many
8.5 Relationships One-to-one Mastering EJB3.0, Chap 9 8.5 Relationships One-to-one Each constituent can have at most one relationship with the other constituent Person : Address Car : Windshield Order : Shipment
Mastering EJB3.0, Chap 9 8.5 Relationships
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9 8.5 Relationships
8.5 Relationships CascadeType PERSIST MERGE REMOVE REFRESH ALL Mastering EJB3.0, Chap 9 8.5 Relationships CascadeType PERSIST Deal with the creation of entities within the database MERGE Deal with entity synchronization REMOVE REFRESH Similar to MERGE, but only pertains to when EntityManager.refresh() is called Do not update the database ALL
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9 8.5 Relationships
8.5 Relationships One-to-many Order : LineItems Customer : Orders Mastering EJB3.0, Chap 9 8.5 Relationships One-to-many Order : LineItems Customer : Orders Company : Employees
Mastering EJB3.0, Chap 9 8.5 Relationships
Mastering EJB3.0, Chap 9 8.5 Relationships
Mastering EJB3.0, Chap 9 8.5 Relationships
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9 8.5 Relationships
Mastering EJB3.0, Chap 9 8.5 Relationships
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9 8.5 Relationships
Mastering EJB3.0, Chap 9
Mastering EJB3.0, Chap 9 8.5 Relationships
8.5 Relationships Join Table Generation Rules Mastering EJB3.0, Chap 9 8.5 Relationships Join Table Generation Rules The name of the join table OwningEntityName_TargetEntityName The name of the first column PropertyName_OwnerEntityPKName The name of the second column PropertyName_TargetEntityPKName The types of the columns Match the primary key types of the tables
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL With JPA, you can EntityManager.find with the entity’s primary key Queries written in JPQL SQL queries native to the underlying database Java Persistence Query Language (JPQL) Platform-independent query language Object-aware
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Use JPQL to query entities
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Named Query
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Creating a named query instance
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL
EJB in Action, Chap 10
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Benefits of Named queries They improve reusability of queries. They improve maintainability of code; queries are not scattered among the business logic. They can enhance performance because they are prepared once and can be efficiently reused.
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Defining statement types
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Defining and using SELECT SELECT c FROM Category c WHERE c.categoryName LIKE :categoryName ORDER BY c.categoryId
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL JPQL query can have the following: A SELECT clause that specifies the object type or entity or values being retrieved A FROM clause that specifies an entity declaration that is used by other clauses An optional WHERE clause to filter the results returned by the query An optional ORDER BY clause to order the results retrieved by the query An optional GROUP BY clause to perform aggregation An optional HAVING clause to perform filtering in conjunction with aggregation
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL JOIN Theta-Joins Relationship joins Outer joins Fetch joins
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Theta-Joins based on arbitrary persistence or association fields in the entities being joined, rather than the relationship defined between them. SELECT i FROM Item i, Category c WHERE i.star = c.rating
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Relationship joins join two or more entities based on their relationships. SELECT u FROM User u INNER JOIN u.Category c WHERE u.userId LIKE ?1
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Outer joins retrieve additional entities that do not match the JOIN conditions when associations between entities are optional SELECT u FROM User u LEFT OUTER JOIN u.Category c WHERE u.userId like ?1
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Fetch joins query for a particular entity but also retrieve its associated entities at the same time SELECT b FROM Bid b FETCH JOIN b.bidder WHERE b.bidDate >= :bidDate
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL GROUPBY and HAVING clauses
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL Follow rules apply to the uses of GROUP BY and HAVING clauses Any arguments in the SELECT clause that is not an aggregation function (SUM, AVG) must appear in the GROUP BY clause The HAVING clause must specify conditions on the GROUP BY arguments or by other aggregation The use of HAVING in the absence of GROUP BY is not required to be supported by EJB 3.0
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL Projection Return a Vector containing an array of type Object for each element.
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL Fun with Queries Dynamic Queries and named Parameters
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL Subqueries
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Defining UPDATE and DELETE UPDATE Seller s SET s.status = 'G', s.commissionRate = 10 WHERE s.lastName like 'PackRat%' DELETE Seller s WHERE s.status = 'Silver'
8.6 Using the query API and JPQL EJB in Action, Chap 10 8.6 Using the query API and JPQL Bulk updates and deletes
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL Rules for Bulk Updates and Deletes Applies to the specified entity and all subclasses of the entity Does not cascade to any related entities The new value specified in a bulk update must be the right type for the update field in the database. Bulk updates occurred directly in database The persistence context is not synchronized with the result of the operation Should be performed either at the beginning of a transaction or in a separate transaction
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL Bulk operations on the RoadVehicle entity
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL
Mastering EJB3.0, Chap 9
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL
8.6 Using the query API and JPQL Mastering EJB3.0, Chap 9 8.6 Using the query API and JPQL
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications When a user places a bid on an item, CaveatEmptor must perform the following tasks, all in a single request: Check that the amount entered by the user is greater than the maximum amount of existing bids for the item. Check that the auction hasn’t yet ended. Create a bid for the item. Inform the user of the outcome of the tasks.
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications
Hibernate in Action, Chap 16
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications The Open Session in View pattern
public class HibernateSessionRequestFilter implements Filter { private SessionFactory sf; private static Log log = ...; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { // Starting a database transaction sf.getCurrentSession().beginTransaction(); // Call the next filter (continue request processing) chain.doFilter(request, response); // Commit the database transaction sf.getCurrentSession().getTransaction().commit(); } catch (Throwable ex) { // Rollback only try { if (sf.getCurrentSession().getTransaction().isActive()) sf.getCurrentSession().getTransaction().rollback(); } catch (Throwable rbEx) { log.error("Could not rollback after exception!", rbEx); rbEx.printStackTrace(); } // Let others handle it... throw new ServletException(ex); public void init(FilterConfig filterConfig) throws ServletException { sf = HibernateUtil.getSessionFactory(); public void destroy() {}
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications The controller code looks much better public void execute() { // Get values from request Session session = HibernateUtil.getSessionFactory().getCurrentSession(); // Load requested Item // Check auction still valid // Check amount of Bid // Add new Bid to Item // Place new Bid in scope for next page // Forward to success page }
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications The transaction commit may occur after the view has been rendered.
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications Migrate the business logic into the domain model
public class Item { ... public Bid placeBid(User bidder, BigDecimal bidAmount, Bid currentMaxBid, Bid currentMinBid) throws BusinessException { // Check highest bid (TODO:Strategy pattern?) if (currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0) { throw new BusinessException("Bid too low."); } // Auction still valid if ( this.getEndDate().before( new Date() ) ) throw new BusinessException("Auction already ended"); // Create new Bid Bid newBid = new Bid(bidAmount, this, bidder); // Place bid for this Item this.addBid(newBid); return newBid;
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications Those couldn’t be moved from controller // Check amount of Bid Query q = session.createQuery("select max(b.amount)" + " from Bid b where b.item = :item"); q.setEntity("item", item); BigDecimal maxBidAmount = (BigDecimal) q.uniqueResult(); if (maxBidAmount.compareTo(bidAmount) > 0) { ... // Forward to error page }
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications public void execute() { Long itemId = ... // Get value from request Long userId = ... // Get value from request BigDecimal bidAmount = ... // Get value from request Session session = HibernateUtil.getSessionFactory().getCurrentSession(); // Load requested Item Item item = (Item) session.load(Item.class, itemId); // Get maximum and minimum bids for this Item Query q = session.getNamedQuery(QUERY_MAXBID); q.setParameter("itemid", itemId);
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications Bid currentMaxBid = (Bid) q.uniqueResult(); q = session.getNamedQuery(QUERY_MINBID); q.setParameter("itemid", itemId); Bid currentMinBid = (Bid) q.uniqueResult(); // Load bidder User bidder = (User) session.load(User.class, userId); try { Bid newBid = item.placeBid(bidder, bidAmount, currentMaxBid, currentMinBid); ... // Place new Bid into request context ... // Forward to success page } catch (BusinessException e) { ... // Forward to appropriate error page }
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications A Generic Data-Access Object Pattern
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications public interface GenericDAO<T, ID extends Serializable> { T findById(ID id, boolean lock); List<T> findAll(); List<T> findByExample(T exampleInstance, String... excludeProperty); T makePersistent(T entity); void makeTransient(T entity); void flush(); void clear(); }
Hibernate in Action, Chap 16 public abstract class GenericHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID> { private Class<T> persistentClass; private Session session; public GenericHibernateDAO() { this.persistentClass = (Class<T>) ( (ParameterizedType) getClass().getGenericSuperclass() ) .getActualTypeArguments()[0]; } public void setSession(Session s) { this.session = s; protected Session getSession() { if (session == null) session = HibernateUtil.getSessionFactory() .getCurrentSession(); return session; public Class<T> getPersistentClass() { return persistentClass; ...
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications Implementing Entity DAOs public interface ItemDAO extends GenericDAO<Item, Long> { Bid getMaxBid(Long itemId); Bid getMinBid(Long itemId); }
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications public class ItemDAOHibernate extends GenericHibernateDAO<Item, Long> implements ItemDAO { public Bid getMaxBid(Long itemId) { Query q = getSession().getNamedQuery("getItemMaxBid"); q.setParameter("itemid", itemId); return (Bid) q.uniqueResult(); } public Bid getMinBid(Long itemId) { Query q = getSession().getNamedQuery("getItemMinBid");
8.7 Creating and Testing Layer Applications Hibernate in Action, Chap 16 8.7 Creating and Testing Layer Applications Using Data-Access Objects
public void execute() { Long itemId = ... // Get value from request Long userId = ... // Get value from request BigDecimal bidAmount = ... // Get value from request // Prepare DAOs ItemDAO itemDAO = new ItemDAOHibernate(); UserDAO userDAO = new UserDAOHibernate(); // Load requested Item Item item = itemDAO.findById(itemId, true); // Get maximum and minimum bids for this Item Bid currentMaxBid = itemDAO.getMaxBid(itemId); Bid currentMinBid = itemDAO.getMinBid(itemId); // Load bidder User bidder = userDAO.findById(userId, false); try { Bid newBid = item.placeBid(bidder, bidAmount, currentMaxBid, currentMinBid); ... // Place new Bid into request context ... // Forward to success page } catch (BusinessException e) { ... // Forward to appropriate error page } Hibernate in Action, Chap 16
public abstract class DAOFactory { /** Hibernate in Action, Chap 16 public abstract class DAOFactory { /** * Factory method for instantiation of concrete factories. */ public static DAOFactory getInstance(Class factory) { try { return (DAOFactory)factory.newInstance(); } catch (Exception ex) { throw new RuntimeException( "Couldn't create DAOFactory: " + factory); } // Add your DAO interfaces here public abstract ItemDAO getItemDAO(); public abstract CategoryDAO getCategoryDAO(); public abstract CommentDAO getCommentDAO(); public abstract UserDAO getUserDAO(); public abstract BillingDetailsDAO getBillingDetailsDAO(); public abstract ShipmentDAO getShipmentDAO();
Hibernate in Action, Chap 16 public class HibernateDAOFactory extends DAOFactory { public ItemDAO getItemDAO() { return (ItemDAO) instantiateDAO(ItemDAOHibernate.class); } ... private GenericHibernateDAO instantiateDAO(Class daoClass) { try { GenericHibernateDAO dao = (GenericHibernateDAO) daoClass.newInstance(); return dao; } catch (Exception ex) { throw new RuntimeException( "Can not instantiate DAO: " + daoClass, ex); // Inline all empty DAO implementations public static class CommentDAOHibernate extends GenericHibernateDAO<Comment, Long> implements CommentDAO {} public static class ShipmentDAOHibernate extends GenericHibernateDAO<Shipment, Long> implements ShipmentDAO {}
Hibernate in Action, Chap 16 public void execute() { Long itemId = ... // Get value from request Long userId = ... // Get value from request BigDecimal bidAmount = ... // Get value from request // Prepare DAOs DAOFactory factory = DAOFactory.instance(Factory.HIBERNATE); ItemDAO itemDAO = factory.getItemDAO(); DAO UserDAO userDAO = factory.getUserDAO(); // Load requested Item Item item = itemDAO.findById(itemId, true); // Get maximum and minimum bids for this Item Bid currentMaxBid = itemDAO.getMaxBid(itemId); Bid currentMinBid = itemDAO.getMinBid(itemId); // Load bidder User bidder = userDAO.findById(userId, false); try { ... }