HIBERNATE/Java & ORACLE
Overview of technology for Hibernate 3
as of 1/2006 By Joel A. Thompson (joel@rhinosystemsinc.com) Goal: Present Hibernate to first time users, and get you started with all the major concepts right away.
copyright 2006, rhinosystemsinc.com all rights reserved
What we'll Cover
• Introduction of HibernateV3 Configuration & Setup of Hibernate/Java • Code • Pros and Cons • RESOURCES • Q & A.
copyright 2006, rhinosystemsinc.com all rights reserved
Intro:About
Hibernate
• www.hibernate.org - Open Source since, and now with JBoss (since late 2003) w/ commercial support & training. Founder: Gavin King • Provides a layer for java to interact with the database.
– Is technically a set of java-class libraries that you use to gain access to your database
• Hibernate caches database objects
– & Hibernate services your Java program
copyright 2006, rhinosystemsinc.com all rights reserved
1/3
Intro:About
Hibernate
• Hibernate layer resides in your JVM. • Improves performance
– objects are cached in JVM and mapped to your object model.
• Used in commercial applications
– JBoss for one (yes, another open source…) – Many more opensource and commercial listed at: http://www.hibernate.org/27.html
copyright 2006, rhinosystemsinc.com all rights reserved
2/3
Intro:About
Hibernate
• Hibernate is highly customizable
– – – – – Caching (2nd level cache). Database dialects Transaction Connection pooling Custom Types
• Or use out of box (recommend changing: connection pooling).
copyright 2006, rhinosystemsinc.com all rights reserved
3/3
Intro:Importance
of DAO
• DAO: Data Access Objects – design/pattern • Purpose is to abstract your calls to the database.
– Don't put SQL directly into your Java/JSP.
• You can change our database with minimal affect on your code • Identify bottle necks and bugs easier.
copyright 2006, rhinosystemsinc.com all rights reserved
1/2
Intro:Importance
of DAO
• Better design translates into easier to understand code. • Hibernate DAO - 3rd party technology
– Benefits of common knowledge – Fixes to technology – Specialized for each database and optimized for database access (caveats).
copyright 2006, rhinosystemsinc.com all rights reserved
2/2
Intro:Comparison
• Problem with SQL
to SQL
– never lived up to promise of standardization amongst database vendors – Uses Jdbc to access database – (no forced design) – Is Relational
• With Hibernate:
– – – – Caching Easier to code Standard access Is Object Oriented and maps to Relational.
copyright 2006, rhinosystemsinc.com all rights reserved
1/2
Intro:Comparison • Speed/performance
to SQL
– Prepared Statements and caching (hib) – Can batch process many DML statements. (hib) – Better performance from PL/SQL (sql/hib) • Maintenance/Updates (hib)
• Legacy system (depends)
– Using hibernate with legacy database systems & Legacy java code retrofit with Hibernate
copyright 2006, rhinosystemsinc.com all rights reserved
2/2
Configuration Hibernate/Java
• Download and install JDK 1.4 or 1.5 • Download version3 from www.hibernate.org • Setup Hibernate's Jars into your project's classpath.
– The hibernate3.jar into your project's classpath; and if need be all the
/lib (if you don't already have them).
copyright 2006, rhinosystemsinc.com all rights reserved
1/5
Config:hibernate.properties
• Make sure that Oracle's client jdbc lib is in your CLASSPATH • Hibernate.properties needs to be in your project's & runtime classpath.
HIBERNATE.PROPERTIES #for OCI (local instance of Oracle, not using tnsnames.ora). hibernate.dialect=org.hibernate.dialect.OracleDialect hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver hibernate.connection.username=joel hibernate.connection.password=xyz hibernate.connection.pool_size=5 hibernate.connection.url=jdbc:oracle:oci:@ hibernate.show_sql=true
copyright 2006, rhinosystemsinc.com all rights reserved
2/5
Config: Download
& Config Xdoclet
[OPTIONAL] • In order to run the "generation" of hibernate XML you need to setup your classpath to include Xdoclet libraries • Download latest (v1.2.3) from
http://xdoclet.sourceforge.net/xdoclet/index.html
(www.xdoclet.org?)
– Download direct from http://sourceforge.net/project/showfiles.php?group_id=31602 – Tag References http://xdoclet.sourceforge.net/xdoclet/tags/hibernate-tags.html
copyright 2006, rhinosystemsinc.com all rights reserved
3/5
config: Download
& Config ANT
[OPTIONAL] • In order to use ANT you'll need to setup your PATH to include ANT. Check – run "ant" • Download latest (v1.6.5) from http://ant.apache.org/
(www.ant.org?)
– Download direct from http://www.axint.net/apache/ant/binaries/apache-ant-1.6.5-bin.zip – Unzip and make sure "ant" is in your path. (right-click my computer ->
properties ->Advanced->Environmental Variables -> update PATH with directory /bin)
copyright 2006, rhinosystemsinc.com all rights reserved
4/5
config: Download
& Config ANT
• SUMMARY:
– JDK [required]: PATH,CLASSPATH – HIBERNATE [required]: CLASSPATH
• ORACLE or DBMS client [required]:
CLASSPATH (connection/lib info w/ hibernate.properties)
– XDOCLET [optional]:CLASSPATH – ANT [optional]:CLASSPATH
copyright 2006, rhinosystemsinc.com all rights reserved
5/5
Code & Fragments
• What we'll cover in the CODE section. For each of the items below you'll see the XML, the DDL SQL, Java code and an explanation.
–Single Entity –Primary Keys –Many-to-One –Many-to-Many –DML (Query, Insert, Update, Delete) –Extra topics
copyright 2006, rhinosystemsinc.com all rights reserved
Code:
Overview
• Hibernate layer is independent of your code • Entities map via hibernate XML • Hibernate & you: DML, caching, isolation levels
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]: Java
POJO Entity
public class Person { Long PERSON_ID=null; //manufactured surrogate key String FIRST_NAME=null; String LAST_NAME=null; Standard get/set public Long getPERSON_ID(){…} need empty public void setPERSON_ID(String) {…} public String getFIRST_NAME(){…} constructor ~ public void setFIRST_NAME(String) {…} public String getLAST_NAME(){…} public void setLAST_NAME (String) {…} }
&
See SAMPLE 0 copyright 2006, rhinosystemsinc.com all rights reserved
1/4
Code[0]: XML
for Entity
SAMPLE0_PERSON_SEQ SAMPLE0_PERSON_SEQ NEXT NEXT
Define the manufactured surrogate primary key, based on SEQUENCE. Also natural composite primary keys: copyright 2006, rhinosystemsinc.com all rights reserved
2/4
Code:
Primary Keys
• All hibernate persisted Entity mappings must have a primary key. • Suggestion: Use surrogate generated keys.
– Hib supports natural keys ( & multi-column).
– Reason:
• Sometimes (rarely) keys will change values • Easier to manage
copyright 2006, rhinosystemsinc.com all rights reserved
3/4
Code[0]: Java
Main Class
//SAVING A NEW OBJECT org.hibernate.Session sess = sessFact.openSession(); //more on SessionFactory in a minute. Person p = new Person(); p.setFIRST_NAME("John"); p.setLAST_NAME("Smith"); Transaction tx = sess.beginTransaction(); sess.saveOrUpdate(p); tx.commit(); At this point, what if we sess.close();
do an update, via SQLPLUS?
See SAMPLE 0
copyright 2006, rhinosystemsinc.com all rights reserved
4/4
Code[0]: Java
public class Person { Long PERSON_ID=null; //manufactured surrogate key String FIRST_NAME=null; String LAST_NAME=null; Set ADDRESSES=null; public Set getADDRESSES() { return ADDRESSES; } public void setADDRESSES(Set ADDRESSES) { this.ADDRESSES = ADDRESSES; } …//rest of get/set methods }
1-to-Many
NEW
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]: Person
…
XML 1-to-Many
… Notice one-to-many ~ …
NEW
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]: Java
public class Address { Long ADDRESS_ID=null; String STREET=null; String APT_NO=null; String CITY=null; String STATE=null; String ZIP=null; Person person=null;// the person this address belongs to. public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } …//rest of get/set methods }
1-to-Many
New Address class
Person reference ~
See Sample 1
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]: Address
XML 1-to-Many
Address class …usual header NOTICE different definition sample of the sequence SAMPLE1_ADDRESS_SEQ INCREMENT BY 1 START WITH 1 Notice variable name in Address class …rest of properties defined
copyright 2006, rhinosystemsinc.com all rights reserved
See Sample 1
Code[0]: main
public static void main(String args[]) …. Address addr = new Address(); Person p = new Person(); p.setFIRST_NAME("John"); p.setLAST_NAME("Thompson"); p.setADDRESSES(new HashSet()); p.getADDRESSES().add(addr); p.setCreated(new Date()); addr.setSTREET("12345 Easy"); addr.setCITY("Sacramento"); addr.setSTATE("CA"); addr.setORDER_POS(new Long(1)); addr.setCreated(new Date()); addr.setPerson(p); … sess.save(p); tx.commit(); … …
1-to-Many
Create an empty "set" and assign to Person Add the address to the "set"
assign person reference to address ~
See Sample 1
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]: Java
public class Address { …same as before
Set persons=null;// the person this address belongs to. public Set getPersons() { return persons; } public void setPersons(Set persons) { this.persons = persons; }
Many-to-Many
NEW ~
…//rest of get/set methods }
See Sample 2
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]: XML
Many-to-Many
…usual header "Set persons=null" in java M-M definition, ~ …rest of properties defined
See Sample 1
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]: Main
Address addr = new Address(); Person p = new Person(); p.setFIRST_NAME("John"); p.setLAST_NAME("Thompson"); p.setADDRESSES(new HashSet()); p.getADDRESSES().add(addr); p.setCreated(new Date()); addr.setSTREET("12345 Easy"); … //revised! for many-to-many addr.setPersons(new HashSet()); addr.getPersons().add(p); //ADD NEW PERSON TO ADDRESS Person p2=new Person(); p2.setFIRST_NAME("Martha"); p2.setLAST_NAME("Thompson"); p2.setADDRESSES(new HashSet()); p2.getADDRESSES().add(addr); addr.getPersons().add(p2);
Many-to-Many
Setup empty Address and Person object Create empty list of Addresses
Martha also lives at the SAME address, here we add the address to the p2 object
~
See Sample 1
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]:
Reference Data
• Data that doesn't change usually loaded at system installation time. (Use 2nd level Cache).
– Examples: STATES, CATEGORY, ZIP..etc.
• Strategy
– Setup XML class with element cache as read-only – Setup cache for relation as read-only – Call a method to load All read-only objects at initialization (actually even everytime). (for example…)
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]:
Reference Data
… For the EVENT class …
copyright 2006, rhinosystemsinc.com all rights reserved
Code[0]:
Reference Data
For the CATEGORY class … Set cache to be read-only … Also - notice no need for a reference back to Event class
---------------------------------------------------------------------------------------------------------In your Java code, load the objects at least once… … org.hibernate.Query q = sess.createQuery("from Category"); q.setCacheMode(org.hibernate.CacheMode.NORMAL); q.setCacheable(true); java.util.List result = q.list(); Make sure your Query sets up the CACHING! (2nd level) ~ …
copyright 2006, rhinosystemsinc.com all rights reserved
Code: • Components
Components
"Fine-grained object Model" - more Classes than Tables
– Value Type – not Entity reference
• Meaning, you want separate Java class (from the main entity) for this property, and yet it is stored in DB with main entity
• Lets Consider ZIP_CODE as example.
• Address w/ ZipCode attribute • ZipCode defines ZIP_CODE and ZIP_4DIGIT_CODE as fields • Address Table has two fields in table (w/ same field names).
copyright 2006, rhinosystemsinc.com all rights reserved
Code:
Component (example)
//JAVA ADDRESS CLASS: public class Address { … ZipCode variable, name is same as ZipCode ZIP=null; mapping below. public ZipCode getZIP(){…} public void setZIP(ZipCode ZIP) } //Address.hbm.xml -----------------------------------------------------------------------------------------…usual header name ~ … …
copyright 2006, rhinosystemsinc.com all rights reserved
Code:
Component (example)
//Java ZipCode Class public class ZipCode { NO ID // Components have NO ID...they are just entirely dependent on // containing Entity - in this case Address - in otherwords, // we want a Java Class representation of ZipCode, but want it // mapped into the Address table with ZIP_CODE and ZIP_4DIGIT_CODE // as attributes of Address table. String ZIP_CODE = ""; String ZIP_4DIGIT_CODE = ""; public String getZIP_4DIGIT_CODE(){…} public void setZIP_4DIGIT_CODE(String ZIP_4DIGIT_CODE){…} public String getZIP_CODE(){…} public void setZIP_CODE(String ZIP_CODE){…} }
Two attributes w/ getters/setters
In this example: Attribute names map directly to database column names ~
copyright 2006, rhinosystemsinc.com all rights reserved
Code:
//SQL for Address table: create table SAMPLE3_Address ( ADDRESS_ID number primary key, STREET varchar2(512), APT_NO varchar2(64), CITY varchar2(512), STATE varchar2(2), ZIP_CODE varchar2(5), ZIP_4DIGIT_CODE varchar2(4) );
Component (example)
Notice same name as ZipCode variables. ~
copyright 2006, rhinosystemsinc.com all rights reserved
Code:
//Java Main Code Address addr = new Address(); Person p = new Person(); p.setFIRST_NAME("John"); p.setADDRESSES(new HashSet()); p.getADDRESSES().add(addr); addr.setSTREET("12345 Easy"); … ZipCode zip=new ZipCode(); zip.setZIP_CODE("95603"); zip.setZIP_4DIGIT_CODE("4456"); addr.setZIP(zip); addr.setPersons(new HashSet()); addr.getPersons().add(p); … sess.saveOrUpdate(p);
Component (example)
Usual initialization here.
Create a ZipCode object, initialize it, and set to the Address Note: query returns an Address object w/ ZipCode filled in automatically. ~
copyright 2006, rhinosystemsinc.com all rights reserved
Code:
Querying
• Hibernate offers a variety of ways to query the objects:
– – – – SQL – straight SQL (parsed SQL 92 standard) HQL – hibernate's query language (SQL based) QBE – query by example Criteria Queries – Object oriented
copyright 2006, rhinosystemsinc.com all rights reserved
Code:
Querying
• HQL simple example:
Use the session to create the Query object.
Query q = sess.createQuery("from Person"); java.util.List result = q.list(); Can also use ? As positional param Then use: // ALSO q.setString(0, Query q = sess.createQuery("from Person p where " +First); q.setString(1, Last); "p.FIRST_NAME = :fname and " + "p.LAST_NAME =:lname"); q.setString("fname", First); //can also use positional parameters Returns a list, that you can iterate q.setString("lname", Last); through and cast the "objects" to java.util.List result = q.list(); Person. ~
See all examples for quering copyright 2006, rhinosystemsinc.com all rights reserved
Code:
• HQL scalar example (from reference.pdf):
Querying
Iterator results = sess.createQuery( "select cat.color, min(cat.birthdate), count(cat) from Cat cat " + "group by cat.color").list().iterator(); while ( results.hasNext() ) Notice alias "cat" lowercase { Object[] column = (Object[]) results.next(); Color type = (Color) column[0]; Notice cast – same as attribute declared in Cat class ~ Date oldest = (Date) column[1]; Integer count = (Integer) column[2]; ..... }
See all examples for quering copyright 2006, rhinosystemsinc.com all rights reserved
Code:
• SQL example:
" " " "
q.addEntity(Person.class); q.setString("fname", First); q.setString("lname", Last); java.util.List result = q.list(); …
SQL Querying
createSQLQuery
org.hibernate.SQLQuery q = sess.createSQLQuery("select * " + from SAMPLE0_PERSON" + where " + FIRST_NAME = :fname " + and LAST_NAME = :lname");
//can also use positional parameters
Tell hibernate about actual class
Bind parameters ~
See all examples for quering
copyright 2006, rhinosystemsinc.com all rights reserved
Code:
SQL Querying
With Alias
• SQL example #2:
+
org.hibernate.SQLQuery q = sess.createSQLQuery("select {Person.*} " + " from SAMPLE0_PERSON Person where " " Person.FIRST_NAME = :fname " + " and Person.LAST_NAME =:lname"); q.addEntity("Person",Person.class); q.setString("fname", First); //can also use positional parameters See also: q.setString("lname", Last); q.addScalar(String columnAlias, Type type). java.util.List result = q.list(); q.addJoin(String alias, String path). Where path is the …
path to the java collection member variable name of the parent class. In our example it would be "Person.ADDRESSES" ~
See all examples for quering
copyright 2006, rhinosystemsinc.com all rights reserved
Pros/Cons
• Cons
– Lots of idiosyncrasies. – caching, flushing, inverse…etc. (But can configure/disable them.) – Learning curve is fairly steep.
(learn a way and stick with it).
– Not good for bulk-inserts (batch processing)
(forced to use PL/SQL within hibernate or jdbc)
– Java-XML-table all defining entity (good and bad) – (xdoclet and other tools – setup system of generating base/core
code elements – use patterns and conventions)
copyright 2006, rhinosystemsinc.com all rights reserved
Pros/Cons
• Pros
– Simple to understand concepts. – Stick with tools and frameworks, then can speed up development time. – Caching for you – so better performance.
(if you don’t use cache, then similar to straight SQL w/ preparedstatement performance).
– Highly extensible and customizable to suite your needs for new development and conversion. – Defacto standard, via OpenSource LGPL license, non proprietary, and known by developer community
(cost, maintenance, bugs..etc.)
copyright 2006, rhinosystemsinc.com all rights reserved
Resources
• Hibernate.org – is the best most up-to-date
– FAQs : http://www.hibernate.org/5.html
• Advanced Problems, Tips and Tricks, Performance and more… • Evaluation- http://www.hibernate.org/263.html
– Doc link: http://www.hibernate.org/5.html – Migration (A MUST!) – http://www.hibernate.org/250.html • Package change: net.sf -> org.hibernate
• SessionFactory • Criteria Query
copyright 2006, rhinosystemsinc.com all rights reserved
Resources
• Hibernate installation
– /doc/{api,other,reference}/en/pdf/hibernate_reference. pdf (great for reference, yet not sufficient for beginners to "learn"). – /eg – samples
copyright 2006, rhinosystemsinc.com all rights reserved
Resources
• Miscellaneous
– Book: Hibernate In Action http://www.manning.com/bauer – Performance #'s:
http://www.sourcelabs.com/?sidemenu=3&page=software&sub=sash_hibernateperftest
• Hibernate user FORUM - http://forum.hibernate.org/
(+200 msg/day) • CaveatEmptor Sample from Hibernate: http://caveatemptor.hibernate.org/
copyright 2006, rhinosystemsinc.com all rights reserved