# Presentation: 189280

## IRMIS rdbCore Java API

*Object-Relational Modelling (ORM)*

## IRMIS rdbCore Java API

**What is rdbCore?**
- Database schema definition (ddl)
*Static for now, but possible to generate for multiple db*
- Process variable crawler
- Java database access layer (also PHP)
**Source code tree overview**

**irmis/**
**    ****apps/           -> pv viewer, component viewer/editor, etc.**
**    ****rdbCore/      -> rdbCore.jar**
**        ****ddl/**
**        ****crawler/perl/**
**        ****db/**
**            ****php/**
**            ****java/**
**                ****gov/anl/aps/irmis/persistence/pv**

## IRMIS rdbCore Java API

**Object-Relational Mapping (ORM)**
- Bridges gap between relational data model and object-oriented data model of applications
- This “gap” responsible for a significant amount of development and maintenance hours
- ORM allows focus on application and data, not transforming between the two models
**Java ORM  <==> Hibernate (Gavin King)**
- LGPL license
- Development began in 2001
- Joined jboss.org in 2003, so commercial support and training available
- Very popular, mature, with active support forums
- Excellent book “Hibernate in Action” (2005 - Bauer, King)

## IRMIS rdbCore Java API

**Data Objects**
- IOC			Record
- IOCBoot			RecordType
- IOCResource		Field
- URI			FieldType
**Data Access Objects**
- IOCBootDAO
- IOCBoot findByIocName(String iocName)
- List findCurrentLoads()
*RecordDAO*
- setRecordTypeConstraint(List recTypes)
- setRecordNameGlobConstraint(String recNamePattern)
- List findByConstraints()

## IRMIS rdbCore Java API

**Code example**
- // retrieve set of current ioc boot instances, and all their process variables
- IOCBootDAO ibDAO = new IOCBootDAO();
- List bootList = null;
- Try {
- 	bootList = ibDAO.findCurrentLoads();
- } catch (DAOException de) {
- 	// handle exception
- }
- // iterate over the results
- Iterator bootIt = bootList.iterator();
- while (bootIt.hasNext()) {
- 	IOCBoot iocBoot = (IOCBoot)bootIt.next();
- 	String iocName = iocBoot.getIoc().getIocName();
- 	List resources = iocBoot.getIocResources();     // eager fetch, so data already here
- 	List records = iocBoot.getRecords();                 // lazy, so addtl. query issued here
- }

## IRMIS rdbCore Java API

**How is this done with Hibernate?**
- Design the object model and relational schema (what order?)
*Depends on whether rdbms schema came first or not*
*APS designed rdbms schema with application in mind, so our object model entities are almost 1-to-1 with relational entities (hibernate still a big plus). *
*Hibernate can auto-generate class source code and/or ddl if desired*
*APS manually created classes and ddl (for now)*

## IRMIS rdbCore Java API

**Hibernate revolves around Session class**

**Session session = sessionFactory.openSession()**

- hibernate.cfg.xml

- IOCBoot.hbm.xml

- Field.hbm.xml

- Record.hbm.xml

- <hibernate-configuration>
-      <session-factory>
-         <property name=“connection.*” value=“blah”/>
-         <property name=“dialect” value=“net.sf.hibernate.dialect.MySQLDialect” />
-         <mapping resource=“gov/anl/aps/irmis/persistence/pv/Record.hbm.xml” />
-         <mapping resource=“gov/anl/aps.irmis/persistence/pv/Field.hbm.xml” />
-         <mapping resource=“gov/anl/aps/irmis/persistence/pv/IOCBoot.hbm.xml” />
-     </session-factory>
- </hibernate-configuration>

**hibernate.cfg.xml**

## IRMIS rdbCore Java API

**Partial Record.hbm.xml mapping **

- <hibernate-mapping>
-       <class name=“gov.anl.aps.irmis.persistence.pv.**Record**”
-           table=“rec” lazy=“true” >
-             <id name=“**id**” column=“rec_id” type=“long” >
-                   <generator class=“native”/>
-             </id>
-             <property name=“**recordName**” type=“string” column=“rec_nm” />
-             <set name=“**fields**” inverse=“true” lazy=“true” >
-                   <key column=“rec_id” />
-                   <one-to-many class=“gov.anl.aps.irmis.persistence.pv.Field” />
-             </set>
-             <many-to-one name=“**recordType**” column=“rec_type_id”
-                   class=“gov.anl.aps.irmis.persistence.pv.RecordType” />
-        </class>
- </hibernate-mapping>

## IRMIS rdbCore Java API

**Record class (Record.java)**

- Public class Record implements Serializable {
-     private Long id;
-     private String recordName;
-     private Set fields = new HashSet();
-     private RecordType recordType;
-     // constructor and accessor methods
-     public Record() {}
-     public Long **getId**() { return this.id; }
-     public void **setId**(Long id) { this.id = id; }
-     public Set **getFields**() { return this.fields; }
-     public void **setFields**(Set fields) {
-         this.fields = fields;
-     }
-     public void **addField**(Field field) {
-         field.setRecord(this);
-         fields.add(field);
-     }

-     public boolean **equals** (Object o) {
-         if (this == other) return true;
-         if (!(other instanceof Record))
-             return false;
-         final Record castO = (Record)o;
-         return this.getIocBoot().getId()==castO
-             .getIocBoot().getId() && this.getRecordName()
-             ==castO.getRecordName();
-     }
-    public int **hashCode**() {
-         int result = HashCodeUtil.SEED;
-         result = HashCodeUtil.hash(result, getIocBoot().getId());
-         result = HashCodeUtil.hash(result, getRecordName());
-         return result;
-     }
- }

## IRMIS rdbCore Java API

**Querying for objects using HQL (Hibernate Query Language)**
- What is HQL?
*minimal OO extension to SQL select*
- Why?
*Query in terms of objects you are interested in*
*Db independence since Hibernate generates SQL for your db*
*Optimization - hibernate generally makes optimal SQL*

- List records = session.find(“select from Record r where r.recordName like ‘ABC%’”);
- List records = session.find(“from Record r join fetch r.fields”);
- IOCBoot boot = session.find(“from IOCBoot ib where ib.ioc.iocName = ‘iocpar01’”);
**- OR - if you absolutely have to use native SQL and JDBC**
- Connection con = session.connection();
- // any JDBC stuff can be done here

## IRMIS rdbCore Java API

**Saving or updating new objects**

- Record rec = new Record();
- rec.setRecordName(“AB:CD:ai”);
- // set remaining fields except id
- Transaction tx = session.beginTransaction();
- session.saveOrUpdate(rec);
- tx.commit();

## IRMIS rdbCore Java API

**Hibernate experience**
- It has a learning curve (2 weeks ?)
- Very active support forums where core developers lurk and answer questions within hours
- Extremely flexible
*Only a small corner of mapping possibilities shown*
*Will work with schemas using natural keys*
*Objects can be mapped to one or many tables, either through composition or association*
*Easy to tweak mappings and watch behavior of SQL (comparing query time using lazy versus eager fetch)*
- Good log output (uses commons-logging and log4j)