HIBERNATEJava ORACLE Overview of technology for Hibernate 3
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 Hibernate. V 3 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 (2 nd 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 - 3 rd 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 to SQL • Problem with 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 to SQL • Speed/performance – 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 version 3 from www. hibernate. org • Setup Hibernate's Jars into your project's classpath. – The hibernate 3. jar into your project's classpath; and if need be all the <hib>/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. Oracle. Dialect hibernate. connection. driver_class=oracle. jdbc. driver. Oracle. Driver 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 (v 1. 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 (v 1. 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 <ant_install>/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 get. PERSON_ID(){…} need empty public void set. PERSON_ID(String) {…} public String get. FIRST_NAME(){…} constructor ~ public void set. FIRST_NAME(String) {…} public String get. LAST_NAME(){…} public void set. LAST_NAME (String) {…} } & See SAMPLE 0 copyright 2006, rhinosystemsinc. com all rights reserved 1/4
Code[0]: XML for Entity <!--Must be named: Person. hbm. xml and reside in CLASSPATH--> <? xml version="1. 0" encoding="UTF-8"? > <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3. 0//EN" "http: //hibernate. sourceforge. net/hibernate-mapping-3. 0. dtd"> <hibernate-mapping> <class name="com. rhinosystemsinc. hibernate. samples_0. Person" table="SAMPLE 0_Person" > <id name="PERSON_ID" column="PERSON_ID" type="java. lang. Long" unsaved-value="null"> <generator class="hilo"> <generator <param name="table">SAMPLE 0_PERSON_SEQ</param> <param name="column">NEXT</param> <param </generator> </id> <property name="FIRST_NAME" type="java. lang. String" update="true" insert="true" column="FIRST_NAME" not-null="true" unique="false" length="100" /> <property name="LAST_NAME"/> </class> </hibernate-mapping> Define the manufactured surrogate primary key, based on SEQUENCE. Also natural composite primary keys: <composite-id> <key-property name="name"/> <key-property name="ssn"/> </composite-id> 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 = sess. Fact. open. Session(); //more on Session. Factory in a minute. Person p = new Person(); p. set. FIRST_NAME("John"); p. set. LAST_NAME("Smith"); Transaction tx = sess. begin. Transaction(); sess. save. Or. Update(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 1 -to-Many public class Person { Long PERSON_ID=null; //manufactured surrogate key String FIRST_NAME=null; String LAST_NAME=null; Set ADDRESSES=null; public Set get. ADDRESSES() { return ADDRESSES; } public void set. ADDRESSES(Set ADDRESSES) { this. ADDRESSES = ADDRESSES; } …//rest of get/set methods } NEW copyright 2006, rhinosystemsinc. com all rights reserved
Code[0]: Person XML 1 -to-Many … <hibernate-mapping> <class name="com. rhinosystemsinc. hibernate. samples_0. Person" table="SAMPLE 0_Person" > … <set name="ADDRESSES" lazy="false" inverse="true" all or save-update-delete cascade="save-update" sort="unsorted" Any records that don't have address will be shown too. outer-join="true"> <key column="PERSON_ID"/> Notice one-to-many ~ <one-to-many class="com. rhinosystemsinc. hibernate. samples_1. Address"/> </set> … </class> </hibernate-mapping> NEW copyright 2006, rhinosystemsinc. com all rights reserved
Code[0]: 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 get. Person() { return person; } public void set. Person(Person person) { this. person = person; } …//rest of get/set methods } Java 1 -to-Many New Address class See Sample 1 Person reference ~ copyright 2006, rhinosystemsinc. com all rights reserved
Code[0]: Address XML 1 -to-Many Address class …usual header <class name="com. rhinosystemsinc. hibernate. samples_1. Address" table="SAMPLE 1_Address" dynamic-update="true"> NOTICE different <id name="ADDRESS_ID" column="ADDRESS_ID" type="java. lang. Long" unsaved-value="null"> definition sample of <generator class="sequence"> the sequence <param name="sequence">SAMPLE 1_ADDRESS_SEQ</param> <param name="parameters">INCREMENT BY 1 START WITH 1</param> </generator> Notice variable name in Address class </id> <many-to-one name="person" class="com. rhinosystemsinc. hibernate. samples_1. Person" For outer-join fetching or use 'select' cascade="save-update" fetch="join" sequential select fetching. N+1 select prob. will always be lazy="false" update="true" eagerly fetched. insert="true" ~ column="PERSON_ID" not-null="false"/> …rest of properties defined See Sample 1 copyright 2006, rhinosystemsinc. com all rights reserved
Code[0]: public static void main(String args[]) …. Address addr = new Address(); Person p = new Person(); p. set. FIRST_NAME("John"); p. set. LAST_NAME("Thompson"); p. set. ADDRESSES(new Hash. Set()); p. get. ADDRESSES(). add(addr); p. set. Created(new Date()); addr. set. STREET("12345 Easy"); addr. set. CITY("Sacramento"); addr. set. STATE("CA"); addr. set. ORDER_POS(new Long(1)); addr. set. Created(new Date()); addr. set. Person(p); … sess. save(p); tx. commit(); … … See Sample 1 main 1 -to-Many Create an empty "set" and assign to Person Add the address to the "set" assign person reference to address ~ copyright 2006, rhinosystemsinc. com all rights reserved
Code[0]: Java Many-to-Many public class Address { …same as before Set persons=null; // the person this address belongs to. public Set get. Persons() { return persons; } public void set. Persons(Set persons) { this. persons = persons; } …//rest of get/set methods } See Sample 2 copyright 2006, rhinosystemsinc. com all rights reserved NEW ~
Code[0]: XML Many-to-Many …usual header <class name=. . . Address> "Set persons=null" in java <set name="persons" Intermediate M-M table="SAMPLE 2_PERSON_ADDRESS"> <key column="ADDRESS_ID"/> M-M definition, <many-to-many class="com. rhinosystemsinc. hibernate. samples_2. Person" referencing the Person class by PERSON_ID column="PERSON_ID"/> ~ </set> …rest of properties defined </class> </hibernate-mapping> See Sample 1 copyright 2006, rhinosystemsinc. com all rights reserved
Code[0]: Address addr = new Address(); Person p = new Person(); p. set. FIRST_NAME("John"); p. set. LAST_NAME("Thompson"); p. set. ADDRESSES(new Hash. Set()); p. get. ADDRESSES(). add(addr); p. set. Created(new Date()); addr. set. STREET("12345 Easy"); … //revised! for many-to-many addr. set. Persons(new Hash. Set()); addr. get. Persons(). add(p); //ADD NEW PERSON TO ADDRESS Person p 2=new Person(); p 2. set. FIRST_NAME("Martha"); p 2. set. LAST_NAME("Thompson"); p 2. set. ADDRESSES(new Hash. Set()); p 2. get. ADDRESSES(). add(addr); addr. get. Persons(). add(p 2); See Sample 1 Main 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 p 2 object copyright 2006, rhinosystemsinc. com all rights reserved ~
Code[0]: Reference Data • Data that doesn't change usually loaded at system installation time. (Use 2 nd 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 … <class name="com. rhinosystemsinc. sample. Event"> For the EVENT class … <many-to-one Variable name for java class name="CATEGORY" Category CATEGORY=null; class="com. rhinosystemsinc. sample. Category" cascade="none" which operations should be cascaded from the update="false" parent object to the associated object insert="false" We will not update or insert from this relationship. ~ column="CATEGORY_ID" not-null="true" /> </class> copyright 2006, rhinosystemsinc. com all rights reserved
Code[0]: Reference Data For the CATEGORY class … <class name="com. rhinosystemsinc. sample. Category" mutable="false"> <cache usage="read-only" /> Set cache to be read-only … </class> 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. create. Query("from Category"); q. set. Cache. Mode(org. hibernate. Cache. Mode. NORMAL); q. set. Cacheable(true); java. util. List result = q. list(); Make sure your Query sets up the CACHING! (2 nd 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/ Zip. Code attribute • Zip. Code defines ZIP_CODE and ZIP_4 DIGIT_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 { … Zip. Code variable, name is same as Zip. Code ZIP=null; mapping below. public Zip. Code get. ZIP(){…} public void set. ZIP(Zip. Code ZIP) } //Address. hbm. xml ---------------------------------------------…usual header <class name="com. rhinosystemsinc. hibernate. samples_3. Address" Notice use of "component", with class table="SAMPLE 3_Address" dynamic-update="true"> name ~ … <component name="ZIP" class="com. rhinosystemsinc. hibernate. samples_3. Zip. Code"> … </class> copyright 2006, rhinosystemsinc. com all rights reserved
Code: Component (example) //Java Zip. Code Class public class Zip. Code { 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 Zip. Code, but want it // mapped into the Address table with ZIP_CODE and ZIP_4 DIGIT_CODE // as attributes of Address table. String ZIP_CODE = ""; String ZIP_4 DIGIT_CODE = ""; public String get. ZIP_4 DIGIT_CODE(){…} public void set. ZIP_4 DIGIT_CODE(String ZIP_4 DIGIT_CODE){…} public String get. ZIP_CODE(){…} public void set. ZIP_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 SAMPLE 3_Address ( ADDRESS_ID number primary key, STREET varchar 2(512), APT_NO varchar 2(64), CITY varchar 2(512), STATE varchar 2(2), ZIP_CODE varchar 2(5), ZIP_4 DIGIT_CODE varchar 2(4) ); Component (example) Notice same name as Zip. Code variables. ~ copyright 2006, rhinosystemsinc. com all rights reserved
Code: //Java Main Code Address addr = new Address(); Person p = new Person(); p. set. FIRST_NAME("John"); p. set. ADDRESSES(new Hash. Set()); p. get. ADDRESSES(). add(addr); addr. set. STREET("12345 Easy"); … Zip. Code zip=new Zip. Code(); zip. set. ZIP_CODE("95603"); zip. set. ZIP_4 DIGIT_CODE("4456"); addr. set. ZIP(zip); addr. set. Persons(new Hash. Set()); addr. get. Persons(). add(p); … sess. save. Or. Update(p); Component (example) Usual initialization here. Create a Zip. Code object, initialize it, and set to the Address Note: query returns an Address object w/ Zip. Code 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: • HQL simple example: Querying Use the session to create the Query object. Query q = sess. create. Query("from Person"); java. util. List result = q. list(); Can also use ? As positional param Then use: // ALSO First); Query q = sess. create. Query("from Person pq. set. String(0, where " + q. set. String(1, Last); "p. FIRST_NAME = : fname and " + "p. LAST_NAME =: lname"); q. set. String("fname", First); //can also use positional parameters Returns a list, that you can iterate q. set. String("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: Querying • HQL scalar example (from reference. pdf): Iterator results = sess. create. Query( "select cat. color, min(cat. birthdate), count(cat) from Cat cat " + "group by cat. color"). list(). iterator(); while ( results. has. Next() ) 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 Querying • SQL example: create. SQLQuery org. hibernate. SQLQuery q = sess. create. SQLQuery("select * " + " from SAMPLE 0_PERSON" + " where " + " FIRST_NAME = : fname " + " and LAST_NAME = : lname"); q. add. Entity(Person. class); q. set. String("fname", First); //can also use positional parameters q. set. String("lname", Last); Tell hibernate about actual java. util. List result = q. list(); 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. create. SQLQuery("select {Person. *} " + " from SAMPLE 0_PERSON Person where " + " Person. FIRST_NAME = : fname " + " and Person. LAST_NAME =: lname"); q. add. Entity("Person", Person. class); q. set. String("fname", First); //can also use positional parameters See also: q. set. String("lname", Last); q. add. Scalar(String column. Alias, Type type). java. util. List result = q. list(); q. add. Join(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 Open. Source 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 • Session. Factory • Criteria Query copyright 2006, rhinosystemsinc. com all rights reserved
Resources • Hibernate installation – <installdir>/doc/{api, other, reference}/en/pdf/hibernate_reference. pdf (great for reference, yet not sufficient for beginners to "learn"). – <installdir>/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) • Caveat. Emptor Sample from Hibernate: http: //caveatemptor. hibernate. org/ copyright 2006, rhinosystemsinc. com all rights reserved
End 0 f Presentation Thank you! • Extra topics session follow, if time. ~ Or ~ • Q&A • Future Questions: email: joel@rhinosystemsinc. com copyright 2006, rhinosystemsinc. com all rights reserved
XDoclet • XDoclet is used to generate hibernate XML files. – You specify annotation tags in your Java code – Run an xdoclet-ANT task on the java code – Make sure xml is in your classpath (the xdocletant will put in src directory) • Hibernate Annotations, next step. See all examples of Xdoclet in the java code copyright 2006, rhinosystemsinc. com all rights reserved
XDoclet example • Person. java • Person. hbm. xml Long PERSON_ID=null; String FNAME=null; /** @hibernate. id /** unsaved-value="null" generator-class="sequence"*/ ** generatorclass="sequence"*/ public Long get. PERSON_ID(){} get public void set. PERSON_ID(Long){} <id name="PERSON_ID" column="PERSON_ID" type="java. lang. Long" unsaved-value="null"> <generator class="sequence"> commentary…-<!– …some xdoclet commentary…--> > </generator> </id> <property Xdoclet Ant task name="LAST_NAME" type="java. lang. String" update="true" insert="true" column="LAST_NAME" /** @hibernate. property */ */ public String get. FNAME(){} public void set. FNAME(String){} /> • Maintain tags in one location - Java • On building (one click) create hbm. xml files See all examples for xdoclet copyright 2006, rhinosystemsinc. com all rights reserved
Topics Not Covered • • • Session. Factory PLSQL Custom User. Type Caching (1 st & 2 nd Level) Transactions and Isolation Levels – JDBC trx semantics – Concurrent Updates and versioning. • Session and Flushing – Session "unit of work" • Interceptors & Logging • Definitions: – Transient, Persistent, Detached • Subclass copyright 2006, rhinosystemsinc. com all rights reserved
- Slides: 50