Sakai Persistence and Intro to Hibernate Aaron Zeckoski
Sakai Persistence and Intro to Hibernate • Aaron Zeckoski • aaronz@vt. edu Sakai Oxford Tetra ELF Workshop Creative Commons Attribution. Share. Alike 2. 5 License Sakai Programmer's Café
What is persistence? • Taking temporary data (like in-memory program data) and storing it in a more permanent form • Putting program data somewhere so you can retrieve it later (e. g. after a restart) • Writing the information in your Java objects somewhere so you can get to it again after they are destroyed 2
How do we persist data in Sakai? • Pretty much always use the database • Some file system storage for tools like resources so data is accessible via Web. Dav • You should probably use the database 3
Databases and Sakai • Settings to control the database that is used are stored in sakai. properties • The sakai. properties file is located in your sakai home (this is configurable but is normally your tomcat home) in the sakai directory • Look for the following line in the file # DATABASE CONFIGURATION 4
Some DB config tips • Always leave auto. dll=true – You might want to turn this off for production environments • HSQLDB is turned on by default, it only stores data in memory by default • HSQLDB works well for development and for demos – Caveat: You cannot look at the HSQLDB database without some serious trickery 5
More DB config tips • My. SQL is easy to setup and use and runs pretty efficiently for development • Allows you to look at the database to see if things are working • Works well on most platforms and tends to get into a lock state somewhat easily which helps you find transaction problems • If all else fails, switch to HSQLDB file storage 6
HSQLDB file storage • To use HSQLDB in file mode (where it stores data on the filesystem), comment out this line: url@javax. sql. Base. Data. Source=jdbc: hsqldb: . • and uncomment this one url@javax. sql. Base. Data. Source= jdbc: hsqldb: ${sakai. home}/db/sakai. db 7
My. SQL config • To use My. SQL, uncomment the six lines under this line: ## My. SQL settings • Comment out the 7 lines under this one: ## HSQLDB settings • Update the username and password lines to match your My. SQL database 8
One last DB tip • You can turn on verbose Hibernate logging in the sakai. properties file • Change the following from false to true # enable hibernate SQL debugging output hibernate. show_sql=false – Note: You do NOT want to leave this on in a production environment 9
3 ways to persist data to the DB JDBC http: //java. sun. com/products/jdbc/ Spring JDBC http: //www. springframework. org/docs/refere nce/jdbc. html Hibernate http: //www. hibernate. org/ 10
JDBC Info • Java Database Connectivity • Industry standard but has some issues: – The developer needs to deal with lot of plumbing and infrastructure, such as endless try-catch-finally-try-catch blocks. – Applications need complex error handling to ensure that connections are properly closed after they're used, which makes the code verbose, bloated, and repetitive. – JDBC uses the rather uninformative SQLException. – JDBC has no exception hierarchy • Bottomline: Don’t use this! From: http: //java. sun. com/products/jdbc/ 11
Spring JDBC Info • Abstraction framework for JDBC – i. e. It does lots of stuff for you! • Some features of Spring JDBC – Jdbc. Dao. Support – super class, provides Jdbc. Template access – Spring provides an abstract exception layer, moving verbose and error-prone exception handling out of application code into the framework. The framework takes care of all exception handling; application code can concentrate on using appropriate SQL. – Spring provides a significant exception hierarchy for your application code to work with in place of SQLException. – For creating instances of oracle. sql. BLOB (binary large object) and oracle. sql. CLOB(character large object), Spring provides the class org. springframework. jdbc. support. lob. Oracle. Lob. Handler. • Bottomline: If you love writing SQL, use this! From: http: //www. springframework. org/docs/reference/jdbc. html 12
Hibernate Info • Object / Relational mapping (ORM) and persistence / query framework – i. e. It does even more stuff for you! • Some features of Hibernate – Hibernate. Dao. Support – super class, easy Hibernate. Template access – Database independence - sits between the database and your java code, easy database switch without changing any code – Object / Relational Mapping (ORM) - Allows a developer to treat a database like a collection of Java objects – Object oriented query language (HQL) - Fully supports polymorphic queries, native SQL, and Criteria queries – Hibernate Mapping - Uses HBM XML files to map value objects (POJOs) to database tables – Transparent persistence - Allows easy saves/delete/retrieve for simple value objects – High performance because it is a fairly lightweight framework From: http: //www. hibernate. org/ 13
More Hibernate Info • Hibernate basically sits between the DB and your code • Can map persistent objects to tables • In Sakai, the Hibernate configuration is set for you already From: http: //www. hibernate. org/hib_docs/v 3/reference/en/html/architecture. html 14
Even more Hibernate Info • Hibernate 2 -tier web architecture • Can send data to JDBC or XML files • Best to just use it the way Sakai does (JDBC) • Bottomline: Use this! From: http: //www. hibernate. org/354. html 15
Hibernate Development • 4 methods of development using Hibernate • Top down (good for existing code) – implement a Java (Java. Beans) object model – write a mapping document by hand, or generate it from XDoclet tags – export the database tables using the Hibernate Tools • Bottom up (good for existing database or code conversion) – – start with an existing data model use the Hibernate Tools to generate the mapping documents use the Hibernate Tools to generate skeletal Java code fill in the business logic by hand • Middle out (good for new development) – – express your conceptual object model directly as a mapping document use the Hibernate Tools to generate skeletal Java code fill in the business logic by hand export the database tables using the Hibernate Tools • Meet in the middle (good for existing JDBC to Hibernate switch) – start with an existing data model and existing Java classes – write a mapping document to adapt between the two models From: http: //www. hibernate. org/355. html 16
Hibernate Tips Avoid primitives • Don’t use primitives for properties on persistent objects – This works fine in general but it does not work if you are doing a find. By. Properties • If you do decide to use primitives, you cannot leave them null/unset when doing a find. By. Properties or they will be set to the default value for that primitive – Things seem to work better when not using primitives sometimes (e. g. Boolean) 17
Hibernate Tips don’t preset values • Don’t set the values of persistent objects in the POJO – This can cause problems with frameworks that expect to be able to instantiate the POJO with all properties unset – It may be more work to set the properties for all non-null attributes but it is worth it 18
Hibernate Tips save all subclasses • If you have any subclasses as properties of a persistent object you should save them before saving the parent class – Hibernate claims that you can just save the parent class in certain cases but it is safer to always save the subclasses separately – The same thing goes for deleting 19
Hibernate Tips non-primitive generated ids • Use non-primitive generated ids for the primary key of persistent objects – It is more efficient and is a good idea in most databases anyway – Use java. lang. Long or java. lang. String for best results • More best practices here: http: //www. hibernate. org/hib_docs/reference/en/html/best-practices. html 20
Hibernate Tools • Hibernate provides a set of Eclipse tools http: //www. hibernate. org/255. html – Mapping Editor: An editor for Hibernate XML mapping files, supporting auto-completion and syntax highlighting – Console: a view in Eclipse. Provides a tree overview of console configurations and interactive view of persistent classes and relationships. Also allows the execution of HQL queries against your database and browsing of results in Eclipse. – Development Wizards: Includes the Hibernate configuration (cfg. xml) files wizard and reverse engineering wizard for turning an existing database schema into POJO source files and HBM files. From: http: //www. hibernate. org/255. html 21
Hibernate in Sakai • 3 ways of using Hibernate in Sakai 1. Create a Session. Factory using settings inside your tool 2. Create a session factory from the global Sakai session. Factory. Base 3. Add our HBMs to the global Sakai session. Factory • Sakai 2. 2+ use Hibernate 3 § Previous versions used Hibernate 2 From: http: //bugs. sakaiproject. org/confluence/display/BOOT/Hibernate+in+Sakai 22
Method 1 • Create a Hibernate Session. Factory using config settings in your tool – You should use this when connecting to an external database – Don’t use this method to connect to the internal Sakai database! – More info on session configuration: http: //www. hibernate. org/hib_docs/reference/en/html/session-configuration. html 23
Method 2 • Create a session factory from the global Sakai Session. Factory. Base – This is not the recommended method but if you are using a single maven project for your app then you have to use it • This method works well for simple tools – Demostrated in tasklist-simple – More complex tools should use method 3 From: http: //bugs. sakaiproject. org/confluence/display/BOOT/Creating+sessions+from+the+Sakai+Session. Factory. Base 24
Method 3 • Add our HBMs to the global Sakai session. Factory – This is the preferred method – Works best for all but the simplest apps – Requires the tool to deploy portions to shared and components so it cannot be used for simple tools • Demonstrated in tasklist From: http: //bugs. sakaiproject. org/confluence/display/BOOT/Using+the+Sakai+global+session. Factory 25
Use the Generic Dao package • The Generic. Dao is an abstraction layer that will allow you to use Hibernate with your persistent objects without needing to write a DAO at all • It has usage information in the javadocs • Highly configurable and extendable • Has no dependencies in the interfaces 26
More on Generic. Dao • Get the code and javadocs from the VT maven repository: – http: //source. edtech. vt. edu/maven/generic-dao/ • Usage is demonstrated in the tasklist code here: – https: //source. sakaiproject. org/contrib/programmer scafe/trunk/tasklist/ 27
Let’s look at some code! • Use the Sakai RAD tool in eclipse to create a simple CRUD app • You can also look at the tasklist code here if you like: – https: //source. sakaiproject. org/contrib/progr ammerscafe/trunk/tasklist/ • Let’s see what it takes to use Hibernate in Sakai… 28
Update project. xml • Add the Hibernate dependency to the tool/project. xml file • Note that we use 3 property variables from master/project. properties <dependency> <group. Id>${sakai. hibernate. group. Id}</group. Id> <artifact. Id>${sakai. hibernate. artifact. Id}</artifact. Id> <version>${sakai. hibernate. version}</version> </dependency> 29
Hibernate Mapping Files • Hibernate can use an xml file to map objects to the database • We will create our mapping file from a simple template attached to the persistence page • For applications with many tables, use a tool to help generate the HBM files 30
Package for the HBM • Create a new Java package for the HBM (mapping file) – org. sakaiproject. toolname. hbm • Create a new file in this package – My. Object. hbm. xml 31
Basic HBM template <? xml version="1. 0"? > <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate Mapping DTD 3. 0//EN" "http: //hibernate. sourceforge. net/hibernate-mapping-3. 0. dtd"> <hibernate-mapping> <class name="org. sakaiproject. toolname. model. My. Object” table="TOOLNAME_MYOBJECT"> <id name="id" type="long"> <generator class="native"> <param name="sequence">MYOBJECT_ID_SEQ</param> </generator> </id> <property name="my. Property" type="string" length="255" not-null="true”/> </class> </hibernate-mapping> 32
Template customization • Change the class name and table name – org. sakaiproject. toolname. model. My. Object • Change the id sequence name • Copy and paste the property block to add the properties from your persistent object – owner – site. Id – creation. Date • Etc… 33
Creating a DAO for Hibernate • Create a new class which implements your DAO interface – Write a DAO interface if you do not have one • Extend Hibernate. Dao. Support • Add import for Hibernate. Dao. Support – Make sure you use the one for hibernate 3 • Or use Generic DAO package! 34
Spring configuration • Now we need to tie everything together with Spring • First we will tell hibernate about our MYObject. hbm. xml mapping file • Next we will give the hibernate stuff to our DAO implementation • Finally we will tie the new DAO to the rest of the webapp 35
Adding our HBMs to the Sakai Global Session. Factory <bean id="org. sakaiproject. yourapp. hibernate. Additional. Hibernate. Mappings" class="org. sakaiproject. springframework. orm. hibernate. impl. Additional. Hibernate. Mappings. Impl"> <property name="mapping. Resources"> <list> <value>org/sakaiproject/yourapp/impl/hbm/Item 1. hbm. xml</value> <value>org/sakaiproject/yourapp/impl/hbm/Item 2. hbm. xml</value> </list> </property> </bean> • This allows us to use our persistent objects with the Sakai Global Session. Factory 36
Define a Hibernate. Template <bean id="org. sakaiproject. tool. tasklist. Hibernate. Template" class="org. springframework. orm. hibernate 3. Hibernate. Template"> <property name="session. Factory"> <ref bean="org. sakaiproject. tasklist. Session. Factory" /> </property> </bean> • Hibernate. Template gives us access to the nice Spring Hibernate functions 37
Inject the Global Session. Factory into the DAO <bean id="org. sakaiproject. yourapp. dao. My. Tool. Dao. Target" class="org. sakaiproject. yourapp. dao. impl. My. Tool. Dao. Impl"> <property name="session. Factory"> <ref bean= "org. sakaiproject. springframework. orm. hibernate. Global. Session. Factory" /> </property> </bean> • This connects the new DAO to hibernate • The DAO implementation should extend Hibernate. Dao. Support 38
Define a declarative transaction interceptor <bean id="org. sakaiproject. yourapp. dao. My. Tool. Dao" class="org. springframework. transaction. interceptor. Transaction. Proxy. Factory. Bean"> <property name="transaction. Manager"> <ref bean="org. sakaiproject. springframework. orm. hibernate. Global. Transaction. Manager" /> </property> <property name="target"> <ref bean="org. sakaiproject. yourapp. dao. My. Tool. Dao. Target"/> </property> <property name="transaction. Attributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> • Without this your operations are not in a transaction and you will see many problems 39
Any questions? • Check out the section on persistence in the programmers café for more information • http: //bugs. sakaiproject. org/confluence/display/BOOT/Persistence • Hibernate: http: //www. hibernate. org/ 40
- Slides: 40