1 / 35

Sakai Persistence and Hibernate

Sakai Persistence and Hibernate. Aaron Zeckoski azeckoski@gmail.com. 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

Télécharger la présentation

Sakai Persistence and Hibernate

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sakai Persistenceand Hibernate Aaron Zeckoski azeckoski@gmail.com

  2. 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 How do we persist data in Sakai?

  3. 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 Databases and Sakai

  4. Only 4 databases are supported for use in Sakai HSQLDB *very* lightweight, pure-Java database, largely for testing and developing, storage either in memory or a flat text file MySQL Open source, pretty good performance, used widely in production, some very unfortunate locking issues Oracle Costs money, high performance, pretty rock solid, works well for those that can/are prepared to afford it 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) Supported databases

  5. 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 Some DB config tips

  6. 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 More DB config tips

  7. To use HSQLDB in file mode (where it stores data on the filesystem), comment out this line: url@javax.sql.BaseDataSource=jdbc:hsqldb:. and uncomment this one url@javax.sql.BaseDataSource=jdbc:hsqldb:${sakai.home}/db/sakai.db HSQLDB file storage

  8. 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 MySQL config

  9. 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 One last DB tip

  10. JDBC http://java.sun.com/products/jdbc/ Spring JDBC http://www.springframework.org/docs/reference/jdbc.html Hibernate http://www.hibernate.org/ 3 ways to persist data to the DB

  11. 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 Persistence rundown URL: http://bugs.sakaiproject.org/confluence/display/BOOT/Persistence

  12. 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 Hibernate Commentary

  13. 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) Hibernate Tips -Avoid primitives

  14. 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 Hibernate Tips - don’t preset values

  15. 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 Hibernate Tips -save dependent objects first

  16. 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 Hibernate Tips - non-primitive generated ids

  17. 3 ways of using Hibernate in Sakai Create a SessionFactory using settings inside your tool Create a SessionFactory from the global Sakai SessionFactoryBase Add our HBMs to the global Sakai SessionFactory Sakai 2.2+ uses Hibernate 3 Previous versions used Hibernate 2 Hibernate in Sakai From: http://bugs.sakaiproject.org/confluence/display/BOOT/Hibernate+in+Sakai

  18. 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 Method 1

  19. 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 Method 2 From: http://bugs.sakaiproject.org/confluence/display/BOOT/Creating+sessions+from+the+Sakai+SessionFactoryBase

  20. 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 Method 3 URL: http://bugs.sakaiproject.org/confluence/display/BOOT/Using+the+Sakai+global+sessionFactory

  21. 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) Use the Generic Dao package URL: http://bugs.sakaiproject.org/confluence/display/BOOT/Generic+DAO+package

  22. 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 More on GenericDao

  23. 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… Look at some sample code

  24. Add the Hibernate dependency to the maven POM.xml file Note that we use dependency management from master POM Update impl maven config <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate</artifactId> </dependency>

  25. 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 Hibernate Mapping Files

  26. 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 Package for the HBM

  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>

  28. 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… Template customization

  29. 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! Creating a DAO for Hibernate

  30. 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 Spring configuration

  31. This allows us to use our persistent objects with the Sakai Global SessionFactory 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>

  32. This connects the new DAO to global Sakai Hibernate The DAO implementation should extend HibernateDaoSupport Inject the Global SessionFactory into the DAO <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>

  33. 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 Define a declarative transaction interceptor <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>

  34. You should be able to start up your app and happily access any database! Hibernate will create or update tables as needed Good to go!

  35. 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/ Spring ORM http://www.springframework.org/docs/reference/orm.html Any questions?

More Related