JDBC vs ORMComparing INGRES-based data access logic
Monica Kurth
Confidential — © 2008 Ingres Corporation Slide
Outline
What is JDBC? What is ORM? Advantages and Disadvantages of using
JDBC vs ORM JDBC Configuration, Issues, Pitfalls JPA Configuration, Issues, Pitfalls Sample application Questions?
Confidential — © 2008 Ingres Corporation Slide
What is JDBC?
Short for Java Database Connectivity Java API that enables Java programs to
execute SQL statements and interact with any SQL-compliant database.
Possible to write a single database application that can run on different platforms and interact with different DBMS.
Similar to ODBC, but designed specifically for Java
Confidential — © 2008 Ingres Corporation Slide
Pros and Cons of JDBC
Clean and simple SQL processing
Good performance with large amounts of data.
Large programming overhead
Transactions and concurrency must be hand-coded in
Awkward way of obtaining and handling connections and
the resulting errors
SQL Logging is not provided and must be coded specifically (INGRES provides utility!)
Confidential — © 2008 Ingres Corporation Slide
JDBC Configuration
Vendor - connect using the Ingres JDBC driver Hostname - the name or IP address Port - the port to connect to, default is II7Database - the name of the database User - the user name to connect with Password - the password
Required Parameters
Confidential — © 2008 Ingres Corporation Slide
JDBC Code Sample
[more code]//Instantiate Driver classClass.forName("com.ingres.jdbc.IngresDriver");
//Create ConnectionConnection connection = DriverManager.getConnection( jdbc:ingres://localhost:II7/demodb, USERNAME, PASSWORD);
//Create SQL statementStatement statement = connection.createStatement();
//Execute SQLstatement.execute(“SELECT * FROM Employee”);
//Tidy up resources – this will need some exception catching etc…statement.close();connection.close();[more code]
Confidential — © 2008 Ingres Corporation Slide
JDBC Configuration – Notes
Leave username and password blank for a local database.
The Ingres driver version must be the one provided by the
local Ingres installation; look for the iijdbc.jar file under
<Ingres dir>\IngresII\ingres\lib
Place iijdbc.jar on the classpath
For SQL Logging, place iijdbc.properties on the classpath
to enable Ingres JDBC driver logging.
Confidential — © 2008 Ingres Corporation Slide
Ingres JDBC logging iijdbc.properties file on classpath
ingres.jdbc.trace.log=/tmp/iijdbc.logingres.jdbc.trace.timestamp=trueingres.jdbc.trace.drv=5ingres.jdbc.trace.ds=5ingres.jdbc.trace.msg=5ingres.jdbc.trace.nl=3
On Windows, this will log to
c:\tmp\iijdbc.log Folder must exist - it will not be created!
Read up more detail on:http://docs.ingres.com/connectivity/JDBCTracing
Set
level 1 (errors)
to level 5 (low level calls)
Confidential — © 2008 Ingres Corporation Slide
What is ORM?
Short for Object Relational Mapping
Lets business code access objects rather than
DB tables
Hides details of SQL queries from OO logic
Makes it easy to extend ORM-based
applications
Based on JDBC ‘under the hood’
Confidential — © 2008 Ingres Corporation Slide
Pro ORM
No need to deal with the database implementation
Little need to write SQL statements = code reduction.
Simple configuration
Entities based on business concepts rather than database structure
Easy navigation of the object graph
Confidential — © 2008 Ingres Corporation Slide
Pro ORM (continued)
Concurrency support- No coding necessary although locking can be manually configured if
desired
Excellent caching built in - e.g. Hibernate 2 levels of caching, detailed configuration possible. Can
greatly increase application performance!
Transaction management and automatic key generation
Very good configurable logging built in
Confidential — © 2008 Ingres Corporation Slide
Against ORM
Can be slow with large Inserts & Updates (batch
processing)
Initially steep learning curve
Sometimes hard to track and optimize
Confidential — © 2008 Ingres Corporation Slide
ORM - JPA - Hibernate
Most ORM tools in the Java world are based on JDBC
Connection configuration easy and similar to JDBC
JPA - first common standard released in May 2006 as part of the Java Standard and Java Enterprise Edition 1.5
Based largely on Hibernate Hibernate still exceeds JPA functionality in
some areas and remains most popular JPA implementation
Confidential — © 2008 Ingres Corporation Slide
Other JPA implementations
OpenJPA – an Apache JPA implementation
Apache Cayenne – another Apache JPA project
JPOX – Open Source JPA implementation
TopLink – Oracle’s JPA implementation
Kodo – BEA’s JPA flavour
Eclipse Link – recently started project for INGRES
Integration – contributions welcome!
Confidential — © 2008 Ingres Corporation Slide
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd“ version="1.0"> <persistence-unit name="jpa-ingres"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.archive.autodetection" value="class"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.connection.driver_class"
value="com.ingres.jdbc.IngresDriver"/> <property name="hibernate.connection.url" value="jdbc:ingres://localhost:II7/
performancedb"/> <property name="hibernate.dialect" value="org.hibernate.dialect.IngresDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties></persistence-unit>
JPA Configuration
XML schema
Persistence Provider: Hibernate
Automatically find persistence
objects in all Java classes
Log all SQL statements
Use Ingres Driver
Connect to DB using JDBC StringUse Hibernate’s Ingres dialect
update the DB schema onlyother options: validate – create - create-drop
Confidential — © 2008 Ingres Corporation Slide
JPA Configuration - Notes
More than one persistence unit can be defined to cater for multiple databases etc.
Changes only in configuration file Actual code not touched by
implementation SQL Logging is easily configured Hibernate implementation needs a
number of Jar files on the classpath
Confidential — © 2008 Ingres Corporation Slide
log4j.appender.FileAppender=org.apache.log4j.FileAppenderlog4j.appender.FileAppender.File=c:/test.loglog4j.appender.FileAppender.layout=org.apache.log4j.PatternLayoutlog4j.appender.FileAppender.layout.ConversionPattern=%d{ABSOLUTE}%5p %c{1}:%L - %m%n
log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE}%5p %c{1}:%L - %m%n
log4j.rootLogger=DEBUG, FileAppender, stdout
log4j.logger.org.hibernate=ERRORlog4j.logger.uk.co.luminary.jdbc=DEBUGlog4j.logger.org.apache.commons.collections=ERROR
Hibernate log4j configuration(similar for other JPA implementations)
log4j.jar and log4j.properties must be placed on classpath
Define File Logger
Define Console Logger
List required Loggers
Set logging levels for different packages in the application and Hibernate.
Allowed are:
FATAL, ERROR, WARN, INFO, DEBUG
Confidential — © 2008 Ingres Corporation Slide
package uk.co.luminary.entity;import javax.persistence.*;
@Entity
@Table(name=“EMP_TABLE") public class Employee{ //define the primary key @Id @GeneratedValue (strategy=GenerationType.AUTO) private Integer id; private String firstName; private String surName; private Date birthdate; private String position; private String notes;
//default constructor public Employee(){ }
JPA entity configuration(independent of JPA implementation)
public Employee(Integer id) { this.id = id; }
//the usual getters and setters public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getFirstName() { return this.firstName; }
[MORE CODE]
tell the JPA this is a mapped entity
the entity’s ID
let the DB use it’s default id generation strategy
(in INGRES, this is SEQUENCE)
Optional: table name; class name = default
Confidential — © 2008 Ingres Corporation Slide
Hibernate – deleting an entityExample log statements
DEBUG - Initializing object from ResultSet: [uk.co.luminary.entity.Employee#21]DEBUG - Hydrating entity: [uk.co.luminary.entity.Employee#21]DEBUG - returning '1960-02-10 00:00:00' as column: birthdate2_0_DEBUG - returning 'John' as column: firstName2_0_DEBUG - returning 'on holiday until August' as column: notes2_0_DEBUG - returning 'Developer' as column: position2_0_DEBUG - returning 'Smith' as column: surName2_0_DEBUG - done processing result set (1 rows)DEBUG - about to close ResultSet (open ResultSets: 1, globally: 1)DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)DEBUG - closing statementDEBUG - total objects hydrated: 1DEBUG - resolving associations for [uk.co.luminary.entity.Employee#21]DEBUG - done materializing entity [uk.co.luminary.entity.Employee#21]DEBUG - initializing non-lazy collectionsDEBUG - done entity loadDEBUG - deleting a persistent instanceDEBUG - deleting [uk.co.luminary.entity.Employee#21]DEBUG - Flushed: 0 insertions, 0 updates, 1 deletions to 1 objectsDEBUG - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collectionsDEBUG - listing entities:DEBUG - uk.co.luminary.entity.Employee{position=Developer, notes=on holiday until August, surName=Smith, firstName=John, birthdate=1960-02-10 00:00:00, id=21}DEBUG - executing flushDEBUG - registering flush beginDEBUG - Deleting entity: [uk.co.luminary.entity.Employee#21]DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)DEBUG - delete from Employee where id=?DEBUG - preparing statementDEBUG - binding '21' to parameter: 1DEBUG - Executing batch size: 1
Confidential — © 2008 Ingres Corporation Slide
Id generation strategies in JPA
javax.persistence.GenerationType.AUTO
javax.persistence.GenerationType.IDENTITY
javax.persistence.GenerationType.SEQUENCE
javax.persistence.GenerationType.TABLE
@Id
@SequenceGenerator(name="s1", sequenceName="SEQ") @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s1")
public long getId() {return id;}
@Id
@TableGenerator(name="tg", table="pk_table", pkColumnName="name", valueColumnName="value", allocationSize=10)
@GeneratedValue(strategy=GenerationType.TABLE, generator="tg")
public long getId() {return id;}
Confidential — © 2008 Ingres Corporation Slide
Id generation for JDBC
Two approaches… Use DB mechanisms to generate IDs
Generate IDs within the Java code, but keep track in DB
Database ID generation
Use Sequence.nextval
Count up from last highest ID in data table
Create separate ID table and select IDs from it
Confidential — © 2008 Ingres Corporation Slide
When to use JDBC
Large updates and inserts
Batch processing
Complicated DB logic that cannot be mapped by JPA Entities
Extensive existing database-centric logic
– Effective stored procedures etc.
SQL commands that cannot be mapped to JPA (dba side)
Confidential — © 2008 Ingres Corporation Slide
When to use JPA
Any system using Java and a RDBMS
New systems with a complex business logic
Existing systems based on JDBC
Especially strong: read-heavy systems
Although little DB knowledge necessary on Java
side, use Ingres expert to make sure DB is well-tuned
Confidential — © 2008 Ingres Corporation Slide
Legacy Systems
When extending – JDBC and JPA can live side by side
Ensure clear boundaries to keep code maintainable
Decide whether both is necessary – slow step-by-step migration possible?
Make sure they don’t clash
Known problems: ID generation – ideally let either JDBC
OR JPA create IDs for any one table/entity
Confidential — © 2008 Ingres Corporation Slide
Migrate old JDBC code to JPA?
Reasoning – performance issues- maintainability?
Many advantages:– More maintainable– More readable– Less code to maintain– Potentially more efficient (due to caching etc.)
Should be done gradually to avoid surprises Extensive testing necessary Can be expensive – replication of JDBC in JPA needs careful re-design
Confidential — © 2008 Ingres Corporation Slide
Example Application
Simple database read/write application JDBC and JPA living side-by-side Logging screen to visualise logic being executed Demonstration of how efficient logging can be added
to existing code Code can be used as base for any other JPA/JDBC
application
Confidential — © 2008 Ingres Corporation Slide
Example Application
Data screen Log screen
Confidential — © 2008 Ingres Corporation Slide
Example Application
Standard hibernate
debug logging
(SELECT)
Confidential — © 2008 Ingres Corporation Slide
Example Application
Custom JDBC debug logging
(SELECT)
Confidential — © 2008 Ingres Corporation Slide
Example Application
Custom JDBC debug logging (INSERT)
Standard Hibernate debug logging (INSERT)
Confidential — © 2008 Ingres Corporation Slide
Questions?