java - Minimal Hibernate 4 XML configuration with Spring 3 for annotation based transaction management and object mapping? -


assuming i've got working spring project minimal amount of configuration needed add in hibernate 4 spring 3 xml configuration? want use annotation based transaction management , have objects mapped using annotations.

note: self-answer q&a style question intended give canonical answer common problem. intend expand question on time keep date hibernate.

i find using hibernate spring's xml config intuitive, if you've never added project before, can pain working correctly. using spring's xml config preferred option hibernate 4.

so you've set spring project , got working. want add hibernate.

i configure hibernate in separate xml file called database-servlet.xml inside web-inf directory, name doesn't matter long on classpath.

my new database-servlet.xml looks this:

<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">  </beans> 

you'll notice imported tx , jdbc spring namespaces. because going use them quite heavily in config file.

first thing want enable annotation based transaction management (@transactional). main reason people use hibernate in spring because spring manage transactions you. add following line configuration file:

<tx:annotation-driven /> 

we need create data source. data source database hibernate going use persist objects. 1 transaction manager have 1 data source. if want hibernate talk multiple data sources have multiple transaction managers.

the type of data source depend on want accomplish. can specify existing database, or can create new in-memory hsql/derby/h2 database comes prepackaged spring. have existing database hibernate connects when deploy project physical testing, use in-memory database unit/integration testing.

i'll show how create in-memory database first.

<jdbc:embedded-database id="datasource" type="hsql">     <jdbc:script location="classpath:/setup.sql" />     .     .     .     <!-- many scripts can run --> </jdbc:embedded-database> 

the above config, create embedded (in-memory) hsql database bean, run script setup.sql , make datasource bean available application context. don't have specify database type hsql default, clear. setup.sql can located anywhere within classpath (web-inf directory usually). can specify many sql scripts like. can set if should run on creation or destruction of database.

this database live , die application. do not use embedded database on production project, 1 power outage, , data gone.

to connect data source existing database configuration different.

<bean id="datasource"      class="org.springframework.jdbc.datasource.drivermanagerdatasource">     <property name="driverclassname" value="" />     <property name="url" value="" />     <property name="username" value="" />     <property name="password" value="" /> </bean> 

the class of bean can implements (i think) javax.sql.datasource write own. example class provided spring, doesn't have own thread pool. popular alternative apache commons org.apache.commons.dbcp.basicdatasource, there many others. i'll explain each of properties below:

  • driverclassname: path jdbc driver. database specific jar should available on classpath. ensure have date version. if using oracle database, you'll need oracledriver. if have mysql database, you'll need mysqldriver. see if can find driver need here quick google should give correct driver.

  • url: url database. jdbc\:oracle\:thin\:\path\to\your\database or jdbc:mysql://path/to/your/database. if google around default location of database using, should able find out should be. if getting hibernateexception message org.hibernate.hibernateexception: connection cannot null when 'hibernate.dialect' not set , following guide, there 90% chance url wrong, 5% chance database isn't started , 5% chance username/password wrong.

  • username: username use when authenticating database.

  • password: password use when authenticating database.

the next thing, set sessionfactory. thing hibernate uses create , manage transactions, , talks database. has quite few configuration options try explain below.

<bean id="sessionfactory"     class="org.springframework.orm.hibernate4.localsessionfactorybean">     <property name="datasource" ref="datasource" />     <property name="packagestoscan" value="au.com.project />     <property name="hibernateproperties">         <props>             <prop key="hibernate.use_sql_comments">true</prop>             <prop key="hibernate.hbm2ddl.auto">validate</prop>         </props>     </property> </bean> 
  • datasource: data source bean. if changed id of datasource, set here.

  • packagestoscan: packages scan find jpa annotated objects. these objects session factory needs manage, pojo's , annotated @entity. more information on how set object relationships in hibernate see here.

  • annotatedclasses (not shown): can provide list of classes hibernate scan if not in same package. should use either packagestoscan or annotatedclasses not both. declaration looks this:

<property name="annotatedclasses">     <list>         <value>foo.bar.package.model.person</value>         <value>foo.bar.package.model.thing</value>     </list> </property> 
  • hibernateproperties: there myriad of these lovingly documented here. main ones using follows:
    • hibernate.hbm2ddl.auto: 1 of hottest hibernate questions details property. see more info. use validate, , set database using either sql scripts (for in-memory), or create database beforehand (existing database).
    • hibernate.show_sql: boolean flag, if true hibernate print sql generates stdout. can configure logger show values being bound queries setting log4j.logger.org.hibernate.type=trace log4j.logger.org.hibernate.sql=debug in log manager (i use log4j).
    • hibernate.format_sql: boolean flag, cause hibernate pretty print sql stdout.
    • hibernate.dialect (not shown, reason): lot of old tutorials out there show how set hibernate dialect use communicate database. hibernate can auto-detect dialect use based on jdbc driver using. since there 3 different oracle dialects , 5 different mysql dialects, i'd leave decision hibernate. full list of dialects hibernate supports see here.

the last 2 beans need declare are:

<bean class="org.springframework.dao.annotation.persistenceexceptiontranslationpostprocessor"     id="persistenceexceptiontranslator" />  <bean id="transactionmanager"      class="org.springframework.orm.hibernate4.hibernatetransactionmanager">     <property name="sessionfactory" ref="sessionfactory" /> </bean> 

the persistenceexceptiontranslator translates database specific hibernateexception or sqlexceptions spring exceptions can understood application context.

the transactionmanager bean controls transactions roll-backs.

note: should autowiring sessionfactory bean dao's.

once you've done this. have add new database-servlet.xml web.xml file.

<context-param> <param-name>contextconfiglocation</param-name>     <param-value>         /web-inf/database-servlet.xml         .         .         .     </param-value> </context-param> 

this should need hibernate working. still need add annotations objects, , add @transactional service layer methods interact dao.

handy hint: if using dependency manager ivy or maven, , pull in spring & hibernate javadocs, can view them in sts xml editor hovering on properties.

how works in practice

in service class, when annotate method @transactional , call method elsewhere few things happen. hibernate transactionmanager uses aop pointcut inject code before method gets invoked. transactionmanager following things (in no particular order):

  • attempts ascertain persistent objects (that knows about) in memory.

  • check sessionfactory existing transactional session, , use sessionfactory create new 1 if 1 doesn't exist, depending on parameters inside annotation.

from point transaction manager records changes make persistent objects discovered, queries run through current session. if exception thrown, simple matter roll has occurred since method invoked.

the sessionfactory bean responsible creating, maintaining, closing , flushing database sessions transactionmanager asks create. that's why autowire sessionfactory dao's , make run queries through it.

one of biggest questions new hibernate users ask "when changes committed?" , answer makes sense when think how transactionmanager works sesisonfactory. database changes flushed , committed when exit service method annotated @transactional. reason is, transaction supposed represent single 'unit' of unbroken work. if goes wrong unit, assumed unit failed , changes should rolled back. sessionfactory flush , clear session when exit service method called originally.

that's not won't flush , clear session while transaction going on. example, if call service method add collection of 5 objects , return total count of objects in database, sessionfactory realise query (select count(*)) requires updated state accurate, , flush addition of 5 objects before running count query. execution this:

//service @override @transactional public long saveandcount(list<foo> listoffoo){     for(foo foo : listoffoo){         //doesn't instantly saved database.         foodao.saveorupdate(foo);     }     /*      * before actual select count(*) query run, sessionfactory      * flush save operation of 5 foo objects.      */     return foodao.count(); } 

to clear, dao have no session management code @ all. have along lines of sessionfactory.getcurrentsession().buildcriteria(foo.class); , that's it. no manipulating instances of session object, no calls flush() or clear(). that's beauty of using hibernate spring.

disclaimer: not know if these examples work standalone hibernate

i not in way affiliated hibernate or hibernate dev team. i'm providing these examples have reference point when i'm answering questions on hibernate tag. these examples , discussions based on own opinion how develop applications using hibernate. these examples in no way comprehensive. i'm basing them on common situations i've used hibernate in past.

if encounter issues trying implement these examples, not comment , expect me fix problem. part of learning hibernate learning in's , out 's of api. if there mistake examples, please feel free edit them.


Comments

Popular posts from this blog

google api - Incomplete response from Gmail API threads.list -

Installing Android SQLite Asset Helper -

Qt Creator - Searching files with Locator including folder -