This document provides an introduction to object-relational mapping using Hibernate. It discusses relational database design, object-oriented design, and the impedance mismatch between the two. It then explains how an ORM like Hibernate can map objects to relational databases while hiding SQL and connection details. Code examples demonstrate using Hibernate and JPA to perform CRUD operations instead of raw JDBC. Configuration of Hibernate and JPA is also summarized.
2. Introduction Hibernate is a tool for storing object data (Java) in a relational database (MySQL, Oracle) Benefits Less code, less repeated code Standards-based (JPA) connection pooling creating new db connections is expensive, reuse them Hides (abstracts away) the relational database as an implementation detail database portability SQL is standard, most vendors offer a dialect Costs Not a perfect abstraction, optimizations at RDB/SQL level required Motivated by work with Gully Burns at ISI and a Flash client (Flex) Talk attempts introductions to ERD and OOD as well as depth 2 Chris Roeder
3. Contents Background Relational Database Design Object Oriented Design Object-Relational Mapping Library Dependencies Meta Data Hibernate, JPA Etc 3 Chris Roeder
4. Relational Database Design Relational Database The world is full of objects (rows), like objects stored in a table keys (SSN, VIN, account number, Student ID, IP and MAC addresses) attributes (every row in a table has the same attributes: 1st NF) relationships between them Datatypes have size. Often the number of characters used: Char(20), Real(10) Logical Criteria for Good Design: Normalization. The attribute should depend on: the key, the whole key (2nd Normal Form), and nothing but the key (3rd Normal Form) so help me Codd. (see E.F. Codd, "A Relational Model of Data for Large Shared Data Banks", Comm. ACM 13 (6), June 1970, pp. 377-387.) Joins are the process an RDB goes through to create relationships expressed in the data The tables are there. The foreign keys are there, but the relationships are created dynamically. This is considered an evolution over earlier Network designs that had static relationships restricting efficient use to the originally supported design. Interesting contrasts to Triple Stores and Graph Databases. 4 Chris Roeder
5. RDB Example Table Person ( ssn integer primary key, first char(20), last char(20) ) Table Car ( vin integer primary key, make char(20), model char(20), owner integer not null) 1234 Chris Roeder 1235 Bill Baumgartner 9876 Subaru Outback 12349877 Toyota Hylander 12359875 Sunbeam Tiger 0001 5 Chris Roeder
6. RDB “primary key” means that data in that column is unique “not null” means you must have a value for that column NULL is an “out-of-band” value distinct from 0 or the empty string Example Query: Select make, model, first, last from Car, Personwhere car.owner = person.ssn The database filters a cross product of rows from each table by the “where” condition, “joining” them. Can declare foreign key constraints (not shown) so that the database only accepts rows where the relationships hold. The 0001 for the owner of the Tiger would be invalid since there is no Person with that id. 6 Chris Roeder
7. RDB: many-many relationships Q: What if the car is owned by more than one person? A: you could flip the relationship around: Have the person table include the VIN Q: What if the car is owned by more than one person and a person can own more than on car? A: you need an intermediary table, a “join table” that represents the collection of owners 7 Chris Roeder
8. RDB: Join Table Table Person ( ssn integer primary key, first char(20), last char(20) ) Table Car ( vin integer primary key, make char(20), model char(20)) Table CarPerson ( ssn integer, vin integer ) 9876 Subaru Outback 9877 Toyota Hylander 9875 Sunbeam Tiger 1234 9876 1235 9877 1234 9875 1235 9875 1234 Chris Roeder 1235 Bill Baumgartner Select make, model, first, last from Car c, Person p, CarPerson cpwhere p.ssn = cp.ssn and cp.vin = c.vin A Join Table is an implementation of a many-many relationship between Car and Person. Doesn’t appear in “logical” models, but does appear in “physical” models 8 Chris Roeder
9. Getting Data from DB to Java:JDBC Example(Java DataBase Connectivity) static List<Restaurant> selectRestaurants() throws SQLException { List<Restaurant> restaurants = new ArrayList<Restaurant>(); stmt = conn.createStatement(); ResultSet results = stmt.executeQuery("select * from " + tableName); ResultSetMetaData rsmd = results.getMetaData(); int numberCols = rsmd.getColumnCount(); while(results.next()) { // get columns by number int id = results.getInt(1); // or by name: results.getInt("id"); String restName = results.getString(2); String cityName = results.getString(3); System.out.println(id + "" + restName + "" + cityName); //Map from database into the object Restaurant r = new Restaurant(restName, cityName); restaurants.add(r); } results.close(); stmt.close(); return restaurants; } 9 Chris Roeder
10. Contents Background Relational Database Design Object Oriented Design Object-Relational Mapping Library Dependencies Meta Data Hibernate, JPA Etc 10 Chris Roeder
11. Object Oriented Design OOA/OOD: Object Oriented Analysis and Design The world is full of objects made up of functions and data. The data (members) are encapsulated. Only the object’s funtions (methods) can access the (private) members. Objects can be composed or aggregated of others: has-a Objects can defined as extensions of others Inheritance, is-a Model data and behavior, Normalize using data and behavior (not just data) Member functions produce “Side Effects” by changing the state of the object, potentially changing future invocations of a function called with the same arguments Considered evil by FP zealots Realistically a bane to concurrent programming 11 Chris Roeder
12. OOD Example Vehicle Location Occupants Car is-a (extends, inherits from) Vehicle Has Engine Has Wheel(s) (relationship to Wheel is one-many) Function Drive() modifies Location Owner Has Vehicle(s) (one-many) 12 Chris Roeder
13. OOD: many-many relationships Many-many relationships in OOD are like what you would think of in code: Two classes, each with a list of references, one for either direction No join table Relationship doesn’t have to be symmetrical It could just be that one side has a list of references to the other It’s many-many because of what the list can contain 13 Chris Roeder
14. OOD Code Example(incomplete psuedo code) Public class Owner { private List<Vehicle> vehicles; } Public class Vehicle { private GPSCoords location; } Public class Car extends Vehicle { public void drive() { location = { 38, 140}; } // note: an Owner can access their Car, but a Car cannot access it’s owner 14 Chris Roeder
15. Contents Background Relational Database Design Object Oriented Design Object-Relational Mapping Library Dependencies Meta Data Hibernate, JPA Etc 15 Chris Roeder
16. ORM: Object Relational Mapping Store data in an RDB, Use it in Java In an organized fashion, with minimal “boilerplate” setup code that is repeated with every project Bridge Differences in Design Join table in OO? Inheritance in RDB? Different Datatypes: Integer, String, Double vs Integer(10), varchar(50), real(10) Moving between the two means you have to deal with this problem: impedance mismatch 16 Chris Roeder
17.
18. ORM: Impedance Mismatchrelationships RDB needs join tables for many:many Java doesn’t RDB relationships are bidirectional Unidirectional in Java. Specify both if you need both 18 Chris Roeder
19. ORM: Impedance MismatchInheritance Java can have two classes that inherit from a base SUV and SportsCar inherit from Car Car lists common attributes and behaviors SUV and SportsCar get them, but they aren’t duplicated (in code). How to represent this in an RDB? 2 tables that include specific and general 3 tables and some fancy joining Chris Roeder 19
20. Contents Background Relational Database Design Object Oriented Design Object-Relational Mapping Library Dependencies Meta Data Hibernate, JPA Etc 20 Chris Roeder
21. Library Dependencies, Flexibility Software Engineering involves flexibility. You may want to change databases, or ORM tools (easily). Older tools required the model’s entity classes (Car, Person, RepairShop, etc.) to import ORM packages into the Java source code. Creating a dependency on that library (jar) Imagine doing this for 100 entities. Newer tools don’t. They allow you to use POJOs… 21 Chris Roeder
22. POJO (Plain Old Java Object) “Plain” means “not an EJB (enterprise java bean)” Martin Fowler, et. al. EJB’s are complicated, POJOs not The “Car” class is about cars and how they change: make, model, year, color, owner mileage, fuel level, position, passengers, cargo, velocity Not about how it is stored between application invocations or how it is “persisted” A “plain” java object, a POJO, does not import persistence library classes, so they can be easily changed. A framework that uses POJOs may be less restrictive 22 Chris Roeder
23. Contents Relational Database Design Object Oriented Design Object-Relational Mapping Library Dependencies Meta Data Hibernate, JPA Etc 23 Chris Roeder
24. Meta Data The ORM tool needs to know more about the POJO than normal Java code would tell it. No resorting to naming conventions. (Ruby on Rails does so: Convention over Configuration) What s the table name? Which member is the key field? What are the details of the relationships (one-many, foreign key field, which is the join table)? This does not include connection information. 24 Chris Roeder
25. Expressing Meta Data Older ORM’s used an XML file to desribe the additional details. This has some drawbacks: Now your class is described in two places. XML meta data grew quite cumbersome An evolution was to put comments in that had the meta-data in the style of Javadoc @author attributes and generate code : Xdoclet (2002-2004) Java 1.5 included the annotations facility (jsr-175 2002) 25 Chris Roeder
26. Example POJO With Annotations @Entity public class Person { private Long id; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; } // snip @ManyToMany(cascade=CascadeType.ALL,mappedBy="authors",targetEntity=Publication.class) public Set<Publication> getPublications() { return publications; } } 26 Chris Roeder
27. Irony The desire for simplicity in POJOs rejects “invasive” technologies Having imports from the ORM is seen as restrictive Precursors to Java Annotations, either XML files or pre-processed annotations as in Xdoclet are non-invasive. The POJO must import the annotation classes So it’s not a pure POJO anymore. 27 Chris Roeder
28. Contents Relational Database Design Object Oriented Design Object-Relational Mapping Library Dependencies Meta Data Hibernate, JPA 28 Chris Roeder
29. Hibernate, JPA Hibernate is an ORM JPA (Java Persistence Architecture) is a spec. Shared, supported and implemented by many vendors, not just Hibernate Came after Hibernate Hibernate has it’s own API Hibernate supports/implements JPA Others (Toplink) support JPA as well 29 Chris Roeder
30. Hibernate Code Example session = sessionFactory.openSession(); session.beginTransaction(); @SuppressWarnings("unchecked") List<Restaurant> result = (List<Restaurant>) session.createQuery( "from Restaurant" ).list(); assertEquals(3, result.size()); for ( Restaurant event : (List<Restaurant>) result ) { System.out.println( "Restaurant: " + event.getId() + ", " + event.getCity() + ", " + event.getRestaurant() ); } session.getTransaction().commit(); session.close(); Chris Roeder 30
31. Code Comparison @SuppressWarnings("unchecked") List<Restaurant> result = (List<Restaurant>) session.createQuery( "from Restaurant" ).list(); Chris Roeder 31 Hibernate JDBC List<Restaurant> restaurants = new ArrayList<Restaurant>(); ResultSet results = stmt.executeQuery("select * from " + tableName); while(results.next()) { // get columns by number int id = results.getInt(1); // or by name: results.getInt("id"); String restName = results.getString(2); String cityName = results.getString(3); Restaurant r = new Restaurant(restName, cityName); restaurants.add(r); }
35. Contents Relational Database Design Object Oriented Design Object-Relational Mapping Library Dependencies Meta Data Hibernate, JPA Etc Chris Roeder 35
36. Sample Code Project “HibernateDemo” In SVN under projects Maven-driven Uses Derby database in embedded mode No db installation required Inlcudes samples: JDBC Hibernate JPA Chris Roeder 36
38. Optimizations (TBC) Query Optimizations Application joins Limiting the size and depth of the resulting object graph Chris Roeder 38
39. Further CodeTalk Topics Object Oriented Design Contrast to Functional Decomposition Contrast to Functional Programming, immutability, side effects Relational Design Joins: cost or benefit? Advanced ORM Relationship Modelling ORM Performance and Optimization Chris Roeder 39
40. References Hibernate in Action, Christian Bauer, Gavin King, Manning Pro JPA 2, Merrick Shincariol, Apress http://docs.jboss.org/hibernate/core/3.6/quickstart/en-US/html_single/#hibernate-gsg-tutorial-basic-entity http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#tutorial-firstapp-firstclass http://blog.springsource.com/2006/05/30/getting-started-with-jpa-in-spring-20/ Chris Roeder 40
41. Thank You Gully Burns Having a project that interfaces with JPA Yuriy Early review Bill Organizing, motivating CCP attention Chris Roeder 41