JDBC vs ORM Comparing INGRES-based data access logic
Monica Kurth 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 Required Parameters
Vendor - connect using the Ingres JDBC driver Hostname - the name or IP address Port - the port to connect to, default is II7 Database - the name of the database User - the user name to connect with Password - the password
Confidential — © 2008 Ingres Corporation Slide JDBC Code Sample
[more code] //Instantiate Driver class Class.forName("com.ingres.jdbc.IngresDriver");
//Create Connection Connection connection = DriverManager.getConnection( jdbc:ingres://localhost:II7/demodb, USERNAME, PASSWORD);
//Create SQL statement Statement statement = connection.createStatement();
//Execute SQL statement.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
Confidential — © 2008 Ingres Corporation Slide Ingres JDBC logging On Windows, this will log to c:\tmp\iijdbc.log . iijdbc.properties file on classpath Folder must exist - it will not be created!
ingres.jdbc.trace.log=/tmp/iijdbc.log ingres.jdbc.trace.timestamp=true ingres.jdbc.trace.drv=5
ingres.jdbc.trace.ds=5 Set ingres.jdbc.trace.msg=5 level 1 (errors) ingres.jdbc.trace.nl=3 to level 5 (low level calls)
Read up more detail on: http://docs.ingres.com/connectivity/JDBCTracing
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 JPA Configuration
XML schema Persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence Provider: http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd“ version="1.0"> Hibernate 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 Hibernate log4j configuration (similar for other JPA implementations) log4j.jar and log4j.properties must be placed on classpath log4j.appender.FileAppender=org.apache.log4j.FileAppender Define File Logger log4j.appender.FileAppender.File=c:/test.log log4j.appender.FileAppender.layout=org.apache.log4j.PatternLayout log4j.appender.FileAppender.layout.ConversionPattern=%d{ABSOLUTE}%5p %c{1}:%L - %m%n log4j.appender.stdout=org.apache.log4j.ConsoleAppender Define Console Logger log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE}%5p %c{1}:%L - %m%n log4j.rootLogger=DEBUG, FileAppender, stdout List required Loggers log4j.logger.org.hibernate=ERROR log4j.logger.uk.co.luminary.jdbc=DEBUG log4j.logger.org.apache.commons.collections=ERROR Set logging levels for different packages in the application and Hibernate. Allowed are: FATAL, ERROR, WARN, INFO, DEBUG Confidential — © 2008 Ingres Corporation Slide JPA entity configuration (independent of JPA implementation) package uk.co.luminary.entity; public Employee(Integer id) import javax.persistence.*; { this.id = id; @Entity tell the JPA this is a mapped entity } @Table(name=“EMP_TABLE") Optional: table name; //the usual getters and setters public class Employee class name = default { public Integer getId() //define the primary key { return this.id; @Id the entity’s ID @GeneratedValue } (strategy=GenerationType.AUTO) private Integer id; public void setId(Integer id) { let the DB use it’s default this.id = id; private String firstName; id generation strategy private String surName; } (in INGRES, this is private Date birthdate; SEQUENCE) private String position; public String getFirstName() private String notes; { return this.firstName; //default constructor } public Employee(){ } [MORE CODE] Confidential — © 2008 Ingres Corporation Slide Hibernate – deleting an entity Example 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 statement DEBUG - total objects hydrated: 1 DEBUG - resolving associations for [uk.co.luminary.entity.Employee#21] DEBUG - done materializing entity [uk.co.luminary.entity.Employee#21] DEBUG - initializing non-lazy collections DEBUG - done entity load DEBUG - deleting a persistent instance DEBUG - deleting [uk.co.luminary.entity.Employee#21] DEBUG - Flushed: 0 insertions, 0 updates, 1 deletions to 1 objects DEBUG - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections DEBUG - 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 flush DEBUG - registering flush begin DEBUG - 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 statement DEBUG - binding '21' to parameter: 1 DEBUG - 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 @Id @SequenceGenerator(name="s1", sequenceName="SEQ") @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s1") public long getId() {return id;} . javax.persistence.GenerationType.TABLE @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? Confidential — © 2008 Ingres Corporation Slide