IRMIS rdb Core Java API ObjectRelational Modelling ORM
IRMIS rdb. Core Java API Object-Relational Modelling (ORM) Argonne National Laboratory Office of Science U. S. Department of Energy A U. S. Department of Energy Office of Science Laboratory Operated by The University of Chicago
IRMIS rdb. Core Java API • • What is rdb. Core? - 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. rdb. Core/ -> rdb. Core. jar ddl/ crawler/perl/ db/ php/ java/ gov/anl/aps/irmis/persistence/pv 2 Pioneering Science and Technology Office of Science U. S. Department of Energy
IRMIS rdb. Core 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) 3 Pioneering Science and Technology Office of Science U. S. Department of Energy
IRMIS rdb. Core Java API • • Data Objects - IOC Record - IOCBoot Record. Type - IOCResource Field - URI Field. Type Data Access Objects - IOCBoot. DAO - IOCBoot find. By. Ioc. Name(String ioc. Name) - List find. Current. Loads() - Record. DAO - set. Record. Type. Constraint(List rec. Types) - set. Record. Name. Glob. Constraint(String rec. Name. Pattern) - List find. By. Constraints() Pioneering Science and Technology Office of Science U. S. Department of Energy 4
IRMIS rdb. Core Java API • Code example // retrieve set of current ioc boot instances, and all their process variables IOCBoot. DAO ib. DAO = new IOCBoot. DAO(); List boot. List = null; Try { boot. List = ib. DAO. find. Current. Loads(); } catch (DAOException de) { // handle exception } // iterate over the results Iterator boot. It = boot. List. iterator(); while (boot. It. has. Next()) { IOCBoot ioc. Boot = (IOCBoot)boot. It. next(); String ioc. Name = ioc. Boot. get. Ioc(). get. Ioc. Name(); List resources = ioc. Boot. get. Ioc. Resources(); // eager fetch, so data already here List records = ioc. Boot. get. Records(); // lazy, so addtl. query issued here } 5 Pioneering Science and Technology Office of Science U. S. Department of Energy
IRMIS rdb. Core 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) 6 Pioneering Science and Technology Office of Science U. S. Department of Energy
IRMIS rdb. Core Java API • Hibernate revolves around Session class hibernate. cfg. xml Session session = session. Factory. open. Session() Record. hbm. xml Field. hbm. xml IOCBoot. hbm. xml hibernate. cfg. xml <hibernate-configuration> <session-factory> <property name=“connection. *” value=“blah”/> <property name=“dialect” value=“net. sf. hibernate. dialect. My. SQLDialect” /> <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> 7 Pioneering Science and Technology Office of Science U. S. Department of Energy
IRMIS rdb. Core 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=“record. Name” 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=“record. Type” column=“rec_type_id” class=“gov. anl. aps. irmis. persistence. pv. Record. Type” /> </class> </hibernate-mapping> Pioneering Science and Technology 8 Office of Science U. S. Department of Energy
IRMIS rdb. Core Java API • Record class (Record. java) Public class Record implements Serializable { private Long id; public boolean equals (Object o) { private String record. Name; if (this == other) return true; private Set fields = new Hash. Set(); if (!(other instanceof Record)) private Record. Type record. Type; return false; // constructor and accessor methods final Record cast. O = (Record)o; public Record() {} return this. get. Ioc. Boot(). get. Id()==cast. O public Long get. Id() { return this. id; } . get. Ioc. Boot(). get. Id() && this. get. Record. Name() public void set. Id(Long id) { this. id = id; } ==cast. O. get. Record. Name(); public Set get. Fields() { return this. fields; } } public void set. Fields(Set fields) { public int hash. Code() { this. fields = fields; int result = Hash. Code. Util. SEED; } result = Hash. Code. Util. hash(result, get. Ioc. Boot(). get. Id()); public void add. Field(Field field) { result = Hash. Code. Util. hash(result, get. Record. Name()); field. set. Record(this); return result; fields. add(field); } } } 9 Pioneering Science and Technology Office of Science U. S. Department of Energy
IRMIS rdb. Core 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. record. Name like ‘ABC%’”); List records = session. find(“from Record r join fetch r. fields”); IOCBoot boot = session. find(“from IOCBoot ib where ib. ioc. Name = ‘iocpar 01’”); - OR - if you absolutely have to use native SQL and JDBC Connection con = session. connection(); // any JDBC stuff can be done here 10 Pioneering Science and Technology Office of Science U. S. Department of Energy
IRMIS rdb. Core Java API • Saving or updating new objects Record rec = new Record(); rec. set. Record. Name(“AB: CD: ai”); // set remaining fields except id Transaction tx = session. begin. Transaction(); session. save. Or. Update(rec); tx. commit(); 11 Pioneering Science and Technology Office of Science U. S. Department of Energy
IRMIS rdb. Core 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 log 4 j) 12 Pioneering Science and Technology Office of Science U. S. Department of Energy
- Slides: 12