Sakai Persistence and Hibernate

35
Creative Commons Attribution- NonCommercial-ShareAlike 2.5 License Sakai Programmer's Café Sakai Persistence and Hibernate Aaron Zeckoski [email protected]

description

Sakai Persistence and Hibernate. Aaron Zeckoski [email protected]. Sakai has a single central database configured Virtually every tool/component uses this Sakai in production is typically a clustered environment, and the clustering implementation is largely based around the database - PowerPoint PPT Presentation

Transcript of Sakai Persistence and Hibernate

Page 1: Sakai Persistence and  Hibernate

Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License Sakai Programmer's Café

Sakai Persistenceand

Hibernate

Aaron [email protected]

Page 2: Sakai Persistence and  Hibernate

2

How do we persist data in Sakai?

• Sakai has a single central database configured– Virtually every tool/component uses this

• Sakai in production is typically a clustered environment, and the clustering implementation is largely based around the database– Tools that will not cluster are very unlikely to be

adopted into the core

• You should use the database in pretty much every case– File system storage can be appropriate for “bulky”

resources (Files or Blobs) so data is accessible via WebDav

Page 3: Sakai Persistence and  Hibernate

3

Databases and Sakai • Settings to control the database that is

used are stored in sakai.properties– This is a standard format Java .properties file

• The sakai.properties file is located in your sakai home in the subdirectory named sakai– this is configurable but is normally your

Tomcat home

• Look for the following line in the file# DATABASE CONFIGURATION

Page 4: Sakai Persistence and  Hibernate

4

Supported databases• Only 4 databases are supported for use in

Sakai1. HSQLDB

– *very* lightweight, pure-Java database, largely for testing and developing, storage either in memory or a flat text file

2. MySQL– Open source, pretty good performance, used widely in

production, some very unfortunate locking issues

3. Oracle– Costs money, high performance, pretty rock solid, works

well for those that can/are prepared to afford it

4. DB2– Costs money, trunk only, similar pros/cons to Oracle

• Since the majority of Sakai code uses raw SQL in some form, adding a new database is a major effort (e.g. DB2, MSSQL)

Page 5: Sakai Persistence and  Hibernate

5

Some DB config tips

• Always leave auto.ddl=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

Page 6: Sakai Persistence and  Hibernate

6

More DB config tips

• MySQL despite being a “production” option is actually really easy to set up for development– Allows you to look at the database through its

console 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

Page 7: Sakai Persistence and  Hibernate

7

HSQLDB file storage

• To use HSQLDB in file mode (where it stores data on the filesystem), comment out this line:

[email protected]=jdbc:hsqldb:.

• and uncomment this [email protected]=

jdbc:hsqldb:${sakai.home}/db/sakai.db

Page 8: Sakai Persistence and  Hibernate

8

MySQL config

• To use MySQL, uncomment the six lines under this line: ## MySQL settings

• Comment out the 7 lines under this one: ## HSQLDB settings

• Update the username and password lines to match your MySQL database

Page 9: Sakai Persistence and  Hibernate

9

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

Page 10: Sakai Persistence and  Hibernate

10

3 ways to persist data to the DB

JDBChttp://java.sun.com/products/jdbc/

Spring JDBChttp://www.springframework.org/docs/reference/jdbc.html

Hibernatehttp://www.hibernate.org/

Page 11: Sakai Persistence and  Hibernate

11

Persistence rundown

• Java Database Connectivity– Don’t use this alone!

• Spring JDBC– If you are good with SQL, this is for you

• Hibernate– Use this for fastest initial development

– Some caveats

URL: http://bugs.sakaiproject.org/confluence/display/BOOT/Persistence

Page 12: Sakai Persistence and  Hibernate

12

Hibernate Commentary• Beyond the hype:

– Hibernate *is* the most popular full ORM persistence framework• probably in any language

– Not to say it is without numerous issues• ORM is a tricky problem and general solutions are very difficult

– Many aspects of the Hibernate framework are “over-eager”• lazy Collections, cascade options, long transactions

– Many aspects of Hibernate are overly rigid• proxy behaviour, initial configuration sets cannot be changed, poor

cross-ClassLoader behaviour

• Advice– Use it cautiously! (pay attention to tips)– Avoid lazy Collections, be conservative with cascade options– In general just use it on one entity at a time, with explicit

save/load on for each database operation– In some cases you may still actually want to fall back to SQL

• recommended by the Hibernate team for certain situations

Page 13: Sakai Persistence and  Hibernate

13

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 findByExample• If you do decide to use primitives, you cannot

leave them null/unset when doing a findByExample 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)

Page 14: Sakai Persistence and  Hibernate

14

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

Page 15: Sakai Persistence and  Hibernate

15

Hibernate Tips -save dependent objects first

• If you have any dependent entities as properties of a persistent object you *must* save them before saving the parent class– Hibernate has numerous “cascade” options

that claim to do this automatically, but it is best to start simple

– The same thing goes for deleting

Page 16: Sakai Persistence and  Hibernate

16

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• This kind of primary key is recommended

– 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

Page 17: Sakai Persistence and  Hibernate

17

Hibernate in Sakai

• 3 ways of using Hibernate in Sakai1. Create a SessionFactory using settings inside

your tool

2. Create a SessionFactory from the global Sakai SessionFactoryBase

3. Add our HBMs to the global Sakai SessionFactory

• Sakai 2.2+ uses Hibernate 3 Previous versions used Hibernate 2

From: http://bugs.sakaiproject.org/confluence/display/BOOT/Hibernate+in+Sakai

Page 18: Sakai Persistence and  Hibernate

18

Method 1

• Create a Hibernate SessionFactory using config settings in your tool– You should use this when connecting to an

external database– Do not 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

Page 19: Sakai Persistence and  Hibernate

19

Method 2

• Create a SessionFactory from the global Sakai SessionFactoryBase– This is not the recommended method but if

you are creating a webapp only project for your app then you have to use it

• This method works OK for simple tools– Demonstrated in tasklist-simple– More complex tools should use method 3

From: http://bugs.sakaiproject.org/confluence/display/BOOT/Creating+sessions+from+the+Sakai+SessionFactoryBase

Page 20: Sakai Persistence and  Hibernate

20

Method 3• Add our HBMs to the global Sakai

SessionFactory using AddableSessionFactoryBean– 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 requires more complexity

• Demonstrated in tasklist

URL: http://bugs.sakaiproject.org/confluence/display/BOOT/Using+the+Sakai+global+sessionFactory

Page 21: Sakai Persistence and  Hibernate

21

Use the Generic Dao package

• The GenericDao is an abstraction layer that will allow you to use Hibernate/JDBC 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 Hibernate/JDBC dependencies in the

interfaces (*any* DAO should be like this)

URL: http://bugs.sakaiproject.org/confluence/display/BOOT/Generic+DAO+package

Page 22: Sakai Persistence and  Hibernate

22

More on GenericDao

• Get the code and Javadocs from the Sakai Maven repository:– http://bugs.sakaiproject.org/confluence/display/BOOT/Generic+DAO+package

• Usage is demonstrated in BlogWow, Evaluation, QnA, and other Sakai apps:– https://source.sakaiproject.org/contrib/

• Also used in the app builder plugin• Used in production apps• Many internal unit tests and usage outside Sakai

Page 23: Sakai Persistence and  Hibernate

23

Look at some sample code

• Look at the tasklist code here if you like:– https://source.sakaiproject.org/contrib/tasklist/trunk/

• You could also use the Sakai app builder tool in Eclipse to create a simple CRUD app to follow along

• Let’s see what it takes to use Hibernate in Sakai…

Page 24: Sakai Persistence and  Hibernate

24

Update impl maven config

• Add the Hibernate dependency to the maven POM.xml file

• Note that we use dependency management from master POM

<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate</artifactId> </dependency>

Page 25: Sakai Persistence and  Hibernate

25

Hibernate Mapping Files

• Hibernate uses an XML file to map Java objects onto database columns

• 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

Page 26: Sakai Persistence and  Hibernate

26

Package for the HBM

• Create a new Java package for the HBM (mapping file)– org.sakaiproject.toolname.impl.hbm

• Create a new file in this package– MyObject.hbm.xml

• This file must end up in shared

Page 27: Sakai Persistence and  Hibernate

27

Basic HBM template<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping> <class name="org.sakaiproject.toolname.model.MyObject" table="TOOLNAME_MYOBJECT"> <id name="id" type="long"> <generator class="native"> <param name="sequence">MYOBJECT_ID_SEQ</param> </generator> </id> <property name="myProperty" type="string" length="255" not-null="true”/> </class>

</hibernate-mapping>

Page 28: Sakai Persistence and  Hibernate

28

Template customization

• Change the class name and table name– org.sakaiproject.toolname.model.MyObject

• Change the id sequence name• Copy and paste the property block to add the

properties from your persistent object– owner– siteId– creationDate

• Etc…

Page 29: Sakai Persistence and  Hibernate

29

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 HibernateDaoSupport– part of Spring-Hibernate

• Add import for HibernateDaoSupport– Make sure you use the one for hibernate 3

• Or use Generic DAO package!

Page 30: Sakai Persistence and  Hibernate

30

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

Page 31: Sakai Persistence and  Hibernate

31

Adding our HBMs to the Sakai Global SessionFactory

<bean id="org.sakaiproject.yourapp.hibernate.AdditionalHibernateMappings"

class="org.sakaiproject.springframework.orm.hibernate.impl.AdditionalHibernateMappingsImpl">

<property name="mappingResources"> <list> <value> org/sakaiproject/yourapp/impl/hbm/Item1.hbm.xml </value> </list> </property></bean>

• This allows us to use our persistent objects with the Sakai Global SessionFactory

Page 32: Sakai Persistence and  Hibernate

32

Inject the Global SessionFactory into the DAO

• This connects the new DAO to global Sakai Hibernate

• The DAO implementation should extend HibernateDaoSupport

<bean id="org.sakaiproject.yourapp.dao.MyToolDaoTarget" class="org.sakaiproject.yourapp.dao.impl.MyToolDaoImpl"> <property name="sessionFactory"> <ref bean="org.sakaiproject.springframework.orm.

hibernate.GlobalSessionFactory" /> </property></bean>

Page 33: Sakai Persistence and  Hibernate

33

Define a declarative transaction interceptor

• If your operations are not in a transaction you will see many problems, especially in MySQL

• This involves much less work than opening and closing transactions in code, and is more reliable

<bean id="org.sakaiproject.yourapp.dao.MyToolDao” class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean=

"org.sakaiproject.springframework.orm.hibernate.GlobalTransactionManager" /> </property> <property name="target"> <ref bean="org.sakaiproject.yourapp.dao.MyToolDaoTarget"/> </property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>

Page 34: Sakai Persistence and  Hibernate

34

Good to go!

• You should be able to start up your app and happily access any database!

• Hibernate will create or update tables as needed

Page 35: Sakai Persistence and  Hibernate

35

Any questions?

• Check out the section on persistence in the Programmers’ Café for more informationhttp://bugs.sakaiproject.org/confluence/display/BOOT/Persistence

• Hibernate: http://www.hibernate.org/

• Spring ORMhttp://www.springframework.org/docs/reference/orm.html