Hibernate
From Kb
Contact Article Author | Blog of Article Author | FirstPartners.net Home | LinkedIn profile of Author
See Also
Standard Hibernate Configuration
- Unless we are using Hibernate-Spring integration, we need a Hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.url">jdbc_url</property> <property name="hibernate.connection.username">username</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">org.hibernate.dialect.OracleDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- Mapping files --> <mapping resource="insert_table_name.hbm.xml"/> </session-factory> </hibernate-configuration>
Read Information from Database with Hibernate
- Create Model Class as POJO
- Add class to hibernate.cfg.xml so that hibernate knows that it needs to be mapped.
- Add information to sample-data.xml so that hbm-ddl can populate sample test data
- Annotate class with hibernate annotations
- Class Level
- @Entity - to mark class for ORM mapping
- @Table(name = "tblName") - if class name not the same as db table name
- Method Level - General
- @Field(name = "db-col-name") - if method name not the same oas db column name
- @NotFound(action= NotFoundAction.IGNORE) - if data not there - returns null instead of exception
- Method Level - Id method
- @Id- marks this field as id
- @GeneratedValue(strategy = GenerationType.AUTO)
- Method Level - Dates
- @Temporal(value = TemporalType.DATE) - almost all date mappings will need this
- Method Level - Association
- protected Set<SubObjectName> subObject= new HashSet<SubObjectName>() - class level variable
- public <SubObjectName> getSubObjectName()
- @OneToMany(fetch = FetchType.EAGER) - marks it as one to many , one to one etc
- @JoinColumn(name="categoryId") - the column (this table) we use for join.
- SubObject should be a hibernate mapped object in it's own right
- Hibernate will step in when getSubObjectName() is called and pull the data from the database
- Class Level
- You have now completed the steps in Appfuse basic persistence
- To read the information from the DB using a DAO (and Unit Test) , follow the Appfuse Hibernate Instructions
Hibernate Sessions
Guide to Hibernate Sessions and Transactions
Hibernate Call Prepared SQL
The use the session as managed by Spring, but to gain more control over it in Code.
- Extend GenericDaoHibernate (appfuse) or HibernateDaoSupport (Spring)
Using Hibernate but managing your own session
List<Job> result = null; Session session = super.getSession(true); try { String queryString ="from myDate where id = ?"; Query qry = session.createQuery(queryString); qry.setInt(0,param); result = qry.list(); } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } finally { super.releaseSession(session); } return result;
Calling PL/SQL or Transact SQL from Hibernate (Stored Procedures)
- Extend GenericDaoHibernate (appfuse) or HibernateDaoSupport (Spring)
public boolean someMethod(int param1) throws Exception { // Local variables Session session = null; String returnValue = null; try { // Get the Hibernate Session session = super.getSession(true); // Get a standard SQL Connection from this Connection hibConnection = session.connection(); CallableStatement storedProc = hibConnection .prepareCall("{call packagename.functionName(?,?)}"); storedProc.setInt(1, param1); storedProc.registerOutParameter(2, Types.VARCHAR); storedProc.executeUpdate(); returnValue = storedProc.getString(2); log.debug("Return Value:" + returnValue); log.debug("hibConnection warnings:" + hibConnection.getWarnings()); hibConnection.close(); hibConnection = null; // session.getTransaction().commit(); } catch (SQLException sqle) { log.debug("Rethrowing Exception", sqle); throw new RpException(sqle); } finally { super.releaseSession(session); session = null; } if (returnValue != null && returnValue.equalsIgnoreCase("Y")) { return true; } // failsafe return false; }
Hibernate Query Language (HQL)
Todo
Get another Model via Join Table and Hibernate Annotations
@ManyToMany(fetch = FetchType.EAGER) @JoinTable( name = "my_join_table", joinColumns = {@JoinColumn(name = "key_for_this_model_on_join_table")}, inverseJoinColumns = @JoinColumn(name = "key_for_target_model_on_join_table") ) public OtherTargetTableModel getViaJoinTable(){ return otherTargetTableModel; //Let hibernate intervene and populate this for us. }
Using Hibernate Criteria to restrict the number of results returned
public List<MyObject> getMyObject(Long id, int maxNumberOfResults) throws RpException { // Local variables List<MyObject> result = null; Session session = super.getSession(true); // use the code in the HibernateDao try { Criteria crit = session.createCriteria(MyObject.class); // Restrict number of results if requested if (maxNumberOfResults > 0) { crit.setMaxResults(maxNumberOfResults); } // restrict by id if (id!= null) { crit.add(Restrictions.eq("id", id)); } // Sort by message log id crit.addOrder(Property.forName("id").asc()); result = crit.list(); if (result == null) { throw new RpException("invalid search result"); } } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } finally { super.releaseSession(session); } return result; }
Hibernate CLOB and BLOB
Hibernate Test Clob Local
To get around the problem / exception Blob may not be manipulated from creating session when testing locally.
- Don't use any of the methods to manipulate the Clob e.g.
- Clob.getSubString()
- Clob.length
- Instead the Clob as a Stream, then convert to a string. Example
Clob sampleClob = Hibernate.createClob("some-content-for-our-test-clob"); CharBuffer tmpChar = CharBuffer.allocate(1000); Reader blobReader = inClob.getCharacterStream(); int readChars = blobReader .read(tmpChar); return tmpChar.toString();
- Will probably need to carry out (Unicode) string conversion - Convert Charbuffer to String
- or try out this approach from the hibernate site - 2nd sample down.
String line; String str = ""; BufferedReader b = new BufferedReader( rs.getCharacterStream( name ) ); try { while( (line = b.readLine()) != null ) { str += line; } } catch (IOException e) { throw new SQLException( e.toString() ); } return str;
Using Hibernate with Dirty Data
By default Hibernate throws an exception when it cannot find the associated data (e.g. we have a foreign key in our table , that doesn't exist in the static lookup table). Exceptions in hibernate are not recoverable, so our hibernate session is toast. Using the attribute below causes a null value to be returned , which we can check for and handle in our code).
import org.hibernate.annotations.NotFoundAction; @NotFound(action= NotFoundAction.IGNORE) public SomeValue getSomeValue(){ ... }

