Your SlideShare is downloading. ×
0
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Orms
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Orms

406

Published on

operational relational mappings

operational relational mappings

Published in: Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
406
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
19
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Glenn Paulley, Director, Engineering http://iablog.sybase.com/paulley ORMs and Hibernate
  • 2. What is object-relational mapping? <ul><li>Object-oriented programming technologies are typically used to implement business logic </li></ul><ul><li>Relational databases are used for persistent data storage </li></ul><ul><li>Impedance mismatch between the two paradigms: objects vs. relations </li></ul><ul><ul><li>Estimated that 30-40% of a JDBC application involves coercing data from tuples to object instances and back again </li></ul></ul><ul><li>ORM toolkits are designed to address this impedance mismatch </li></ul><ul><ul><li>61 different ORM toolkits are listed in Wikipedia for Java, C++, Delphi, Ruby, .NET, PHP, Python, Perl </li></ul></ul>
  • 3. What is object-relational mapping? <ul><li>To exploit object behaviour fully, data-access from within an object-oriented programming language should offer: </li></ul><ul><ul><li>Separation of concerns </li></ul></ul><ul><ul><li>Information hiding </li></ul></ul><ul><ul><li>Inheritance </li></ul></ul><ul><ul><li>Change detection </li></ul></ul><ul><ul><li>Uniqueness capability </li></ul></ul><ul><ul><li>Database independence </li></ul></ul>
  • 4. Change detection <ul><li>ORM toolkits require mechanisms to track changes to objects made by the application </li></ul><ul><ul><li>When a transaction is complete, write the changes to the database within an atomic transaction </li></ul></ul><ul><ul><li>Need appropriate guarantees to prevent lost updates </li></ul></ul>
  • 5. Uniqueness <ul><li>Mappings are usually a correspondence between a row in a normalized table and a class instance </li></ul><ul><ul><li>Specified using metadata </li></ul></ul><ul><ul><li>For example, a row of the Employee table will correspond to an instance of the Employee object within the application </li></ul></ul><ul><ul><li>Mappings are often not isomorphic </li></ul></ul><ul><ul><ul><li>Sophisticated ORMs such as Hibernate and LINQ permit object models that differ substantially from the underlying relational store </li></ul></ul></ul><ul><ul><ul><li>Object-oriented language features offer greater semantic flexibility in application design than 1NF values from a relational database </li></ul></ul></ul><ul><li>Need to establish a correspondence between an in-memory object and a database row </li></ul><ul><ul><li>Must be independent of how the object was acquired: a database query, or navigating a reference to another object </li></ul></ul><ul><ul><li>Predicated on the existence of primary keys in the database </li></ul></ul>
  • 6. Database independence <ul><li>Many ORM toolkits attempt to offer database independence, so that applications can be ported from one DBMS to another </li></ul><ul><ul><li>Create common APIs and models to interact with a variety of DBMS platforms </li></ul></ul><ul><li>Useful with mobilized applications where the consolidated database is one DBMS, and local databases are different </li></ul>
  • 7. Why are ORMs useful? <ul><li>Eliminates tedious, repetitive code that instantiates object instances from tuples using a SELECT statement and a CURSOR </li></ul><ul><li>Insulates, to some extent, the application developer from vendor-specific SQL extensions </li></ul><ul><li>Permits the application developer to exploit object-orientation and model and manipulate the application view differently from the relational model </li></ul><ul><li>Data manipulation can be done at the object level, rather than (only) at a SQL statement level </li></ul>
  • 8. Challenges of ORMs <ul><li>ORM toolkits introduce an additional level of complexity to the application </li></ul><ul><ul><li>Example: Java Hibernate 3.2.6 is </li></ul></ul><ul><ul><ul><li>266 packages, 1938 classes, 18,680 functions, over 118K LOC </li></ul></ul></ul><ul><ul><li>Can be difficult to debug, perform performance analysis </li></ul></ul><ul><ul><ul><li>Most frameworks suffer from a lack of appropriate tools </li></ul></ul></ul><ul><li>Performance analysis is problematic because the application’s behaviour is not tied directly to specific interactions with the database </li></ul><ul><ul><li>Complex mappings may cause very complex SQL queries to be generated </li></ul></ul><ul><ul><li>Can be difficult for the application developer to understand what caused their construction </li></ul></ul>
  • 9. Complex SQL (LINQ generated) <ul><li>SELECT </li></ul><ul><li>[Project9].[ContactID] AS [ContactID],[Project9].[C1] AS [C1],[Project9].[C2] AS [C2],[Project9].[ContactID1] AS [ContactID1],[Project9].[SalesOrderID] AS [SalesOrderID], </li></ul><ul><li>[Project9].[TotalDue] AS [TotalDue] </li></ul><ul><li>FROM ( SELECT         [Distinct1].[ContactID] AS [ContactID],        1 AS [C1],        [Project8].[ContactID] AS [ContactID1],        [Project8].[SalesOrderID] AS [SalesOrderID], </li></ul><ul><li>        [Project8].[TotalDue] AS [TotalDue],        [Project8].[C1] AS [C2] </li></ul><ul><li>        FROM   </li></ul><ul><li>(SELECT DISTINCT   [Extent1].[ContactID] AS [ContactID]     </li></ul><ul><li>            FROM  [DBA].[Contact] AS [Extent1] </li></ul><ul><li>                          INNER JOIN [DBA].[SalesOrderHeader] AS [Extent2] </li></ul><ul><li>ON  EXISTS (SELECT   cast(1 as bit) AS [C1] </li></ul><ul><li>                        FROM    ( SELECT cast(1 as bit) AS X ) AS [SingleRowTable1] </li></ul><ul><li>                        LEFT OUTER JOIN  (SELECT [Extent3].[ContactID] AS [ContactID] </li></ul><ul><li>                                FROM [DBA].[Contact] AS [Extent3]  WHERE [Extent2].[ContactID] = [Extent3].[ContactID] )AS [Project1] ON cast(1 as bit) = cast(1 as bit) </li></ul><ul><li>                        LEFT OUTER JOIN  (SELECT  [Extent4].[ContactID] AS [ContactID] </li></ul><ul><li>                                FROM [DBA].[Contact] AS [Extent4]  WHERE [Extent2].[ContactID] = [Extent4].[ContactID] ) AS [Project2] ON cast(1 as bit) = cast(1 as bit) </li></ul><ul><li>                        WHERE ([Extent1].[ContactID] = [Project1].[ContactID]) OR (([Extent1].[ContactID] IS NULL) AND ([Project2].[ContactID] IS NULL))  ) </li></ul><ul><li>) AS [Distinct1] </li></ul><ul><li>  LEFT OUTER JOIN  </li></ul><ul><li>  (SELECT  [Extent5].[ContactID] AS [ContactID],  [Extent6].[SalesOrderID] AS [SalesOrderID],  [Extent6].[TotalDue] AS [TotalDue],   1 AS [C1] </li></ul><ul><li>                FROM  [DBA].[Contact] AS [Extent5] </li></ul><ul><li>                 INNER JOIN [DBA].[SalesOrderHeader] AS [Extent6] </li></ul><ul><li>   ON  EXISTS (SELECT    cast(1 as bit) AS [C1] </li></ul><ul><li>                        FROM    ( SELECT cast(1 as bit) AS X ) AS [SingleRowTable2] </li></ul><ul><li>                        LEFT OUTER JOIN  (SELECT  [Extent7].[ContactID] AS [ContactID] </li></ul><ul><li>                                FROM [DBA].[Contact] AS [Extent7]  WHERE [Extent6].[ContactID] = [Extent7].[ContactID] )AS [Project5] ON cast(1 as bit) = cast(1 as bit) </li></ul><ul><li>                        LEFT OUTER JOIN  (SELECT  [Extent8].[ContactID] AS [ContactID] </li></ul><ul><li>                                FROM [DBA].[Contact] AS [Extent8]  WHERE [Extent6].[ContactID] = [Extent8].[ContactID] )AS [Project6] ON cast(1 as bit) = cast(1 as bit)   </li></ul><ul><li>                       WHERE ([Extent5].[ContactID] = [Project5].[ContactID]) OR (([Extent5].[ContactID] IS NULL) AND ([Project6].[ContactID] IS NULL)) </li></ul><ul><li>                ) </li></ul><ul><li>) AS [Project8] </li></ul><ul><li>ON ([Project8].[ContactID] = [Distinct1].[ContactID]) OR (([Project8].[ContactID] IS NULL) AND ([Distinct1].[ContactID] IS NULL)) </li></ul><ul><li>)  AS [Project9] </li></ul><ul><li>ORDER BY [Project9].[ContactID] ASC, [Project9].[C2] ASC </li></ul>
  • 10. Equivalent SQL query <ul><li>select  Extent6.ContactID,  </li></ul><ul><li>1 as C1,  </li></ul><ul><li>1 as C2, </li></ul><ul><li>Extent6.ContactID as ContactID1,   </li></ul><ul><li>Extent6.SalesOrderID as SalesOrderID, </li></ul><ul><li>Extent6.TotalDue as TotalDue </li></ul><ul><li>from DBA.SalesOrderHeader as Extent6 </li></ul><ul><li>order by Extent6.ContactID asc </li></ul><ul><li>Can your query optimizer get there? </li></ul>
  • 11. Challenges of ORMs <ul><li>Object-instance-at-a-time navigation through the object model can result in multiple, separate interactions to the database server to retrieve the rows to create the objects </li></ul><ul><ul><li>Termed the N+1 Selects problem </li></ul></ul><ul><ul><li>Application developer must tradeoff prefetching applicability in various scenarios </li></ul></ul><ul><ul><li>Objects are not partially instantiated; all object attributes are required for the constructor </li></ul></ul><ul><li>Transactional semantics are complex once caching is introduced </li></ul><ul><ul><li>Transactional semantics often differ across DBMSs, even with the identical isolation level </li></ul></ul><ul><ul><li>Developers must (still) be aware of the potential for lost updates </li></ul></ul>
  • 12. Challenges of ORMs <ul><li>The SQL dialect supported by ORM toolkits is typically a very restricted subset of ANSI SQL </li></ul><ul><li>ORM toolkits often support only limited, straightforward DDL for schema creation/modification </li></ul><ul><ul><li>Not recommended for production applications </li></ul></ul>
  • 13. Important aspects of ORM toolkits <ul><li>Mapping specification </li></ul><ul><li>Query language </li></ul><ul><li>Persistence </li></ul><ul><li>Class inheritance </li></ul><ul><li>Fetch strategies </li></ul><ul><li>Caching </li></ul><ul><li>We look and see how these are implemented in Hibernate, a popular open-source ORM toolkit for Java applications </li></ul>
  • 14. <ul><li>Hibernate as an example of an ORM </li></ul>
  • 15. Brief introduction to Hibernate <ul><li>Open-source, LGPL Java ORM toolkit </li></ul><ul><li>Originally developed by Christian Bauer, Gavin King, and a worldwide team of developers </li></ul><ul><li>Now maintained by a team at JBoss (Redhat) led by Steve Ebersole </li></ul><ul><li>Ported to the .NET environment (C#), called Nhibernate </li></ul><ul><li>http://hibernate.org </li></ul>
  • 16. Hibernate mapping specification <ul><li>CREATE TABLE &quot;GROUPO&quot;.&quot;SalesOrders&quot; ( </li></ul><ul><li>&quot;ID&quot; integer NOT NULL DEFAULT autoincrement </li></ul><ul><li>,&quot;CustomerID&quot; integer NOT NULL </li></ul><ul><li>,&quot;OrderDate&quot; date NOT NULL </li></ul><ul><li>,&quot;FinancialCode&quot; char(2) NULL </li></ul><ul><li>,&quot;Region&quot; char(7) NULL </li></ul><ul><li>,&quot;SalesRepresentative&quot; integer NOT NULL </li></ul><ul><li>,CONSTRAINT &quot;SalesOrdersKey&quot; PRIMARY KEY (&quot;ID&quot;) </li></ul><ul><li>) </li></ul><ul><li>ALTER TABLE &quot;GROUPO&quot;.&quot;SalesOrders“ </li></ul><ul><li>ADD FOREIGN KEY &quot;FK_SalesRepresentative_EmployeeID&quot; (&quot;SalesRepresentative“) REFERENCES &quot;GROUPO&quot;.&quot;Employees&quot; (&quot;EmployeeID&quot;) </li></ul><ul><li>ALTER TABLE &quot;GROUPO&quot;.&quot;SalesOrders“ </li></ul><ul><li>ADD FOREIGN KEY &quot;FK_FinancialCode_Code&quot; (&quot;FinancialCode&quot;) </li></ul><ul><li>REFERENCES &quot;GROUPO&quot;.&quot;FinancialCodes&quot; (&quot;Code“) </li></ul><ul><li>ON DELETE SET NULL </li></ul><ul><li>ALTER TABLE &quot;GROUPO&quot;.&quot;SalesOrders“ </li></ul><ul><li>ADD FOREIGN KEY &quot;FK_CustomerID_ID&quot; (&quot;CustomerID&quot;) </li></ul><ul><li>REFERENCES &quot;GROUPO&quot;.&quot;Customers&quot; (&quot;ID“) </li></ul>
  • 17. Hibernate mapping specification <ul><li>Hibernate mapping file SalesOrders.hbm.xml: </li></ul><ul><li><?xml version=&quot;1.0&quot;?> </li></ul><ul><li><!DOCTYPE hibernate-mapping PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot; </li></ul><ul><li>&quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;> </li></ul><ul><li><!-- Generated Mar 3, 2009 11:59:55 AM by Hibernate Tools 3.2.2.GA --> </li></ul><ul><li><hibernate-mapping> </li></ul><ul><li><class name=&quot;SalesOrders&quot; table=&quot;SalesOrders&quot;> </li></ul><ul><li><comment>sales orders that customers have submitted to the sporting goods company</comment> </li></ul><ul><li><id name=&quot;id&quot; type=&quot;int&quot;> </li></ul><ul><li><column name=&quot;ID&quot; /> </li></ul><ul><li><generator class=&quot;assigned&quot; /> </li></ul><ul><li></id> </li></ul><ul><li><many-to-one name=&quot;employees&quot; class=&quot;Employees&quot; fetch=&quot;select&quot;> </li></ul><ul><li><column name=&quot;SalesRepresentative&quot; not-null=&quot;true&quot; /> </li></ul><ul><li></many-to-one> </li></ul><ul><li><many-to-one name=&quot;financialCodes&quot; class=&quot;FinancialCodes&quot; fetch=&quot;select&quot;> </li></ul><ul><li><column name=&quot;FinancialCode&quot; length=&quot;2&quot; /> </li></ul><ul><li></many-to-one> </li></ul><ul><li><many-to-one name=&quot;customers&quot; class=&quot;Customers&quot; fetch=&quot;select&quot;> </li></ul><ul><li><column name=&quot;CustomerID&quot; not-null=&quot;true&quot; /> </li></ul><ul><li></many-to-one> </li></ul><ul><li><property name=&quot;orderDate&quot; type=&quot;date&quot;> </li></ul><ul><li><column name=&quot;OrderDate&quot; length=&quot;10&quot; not-null=&quot;true&quot; /> </li></ul><ul><li></property> .............[snip] </li></ul><ul><li></class> </li></ul><ul><li></hibernate-mapping> </li></ul>
  • 18. Java class implementation <ul><li>// default package </li></ul><ul><li>// Generated Mar 3, 2009 1:39:06 PM by Hibernate Tools 3.2.2.GA </li></ul><ul><li>import java.util.Date; </li></ul><ul><li>import java.util.HashSet; </li></ul><ul><li>import java.util.Set; </li></ul><ul><li>/** </li></ul><ul><li>* SalesOrders generated by hbm2java </li></ul><ul><li>*/ </li></ul><ul><li>public class SalesOrders implements java.io.Serializable { </li></ul><ul><li>private int id; </li></ul><ul><li>private Employees employees; </li></ul><ul><li>private FinancialCodes financialCodes; </li></ul><ul><li>private Customers customers; </li></ul><ul><li>private Date orderDate; </li></ul><ul><li>private String region; </li></ul><ul><li>private Set salesOrderItemses = new HashSet(0); </li></ul><ul><li>public SalesOrders() { </li></ul><ul><li>} </li></ul><ul><li>public SalesOrders(int id, Employees employees, Customers customers, </li></ul><ul><li>Date orderDate) { </li></ul><ul><li>this.id = id; </li></ul><ul><li>this.employees = employees; </li></ul><ul><li>this.customers = customers; </li></ul><ul><li>this.orderDate = orderDate; </li></ul><ul><li>} </li></ul>
  • 19. HQL: Hibernate Query Language <ul><li>Subset of ANSI query specification with support for </li></ul><ul><ul><li>DISTINCT </li></ul></ul><ul><ul><li>GROUP BY, simple aggregation </li></ul></ul><ul><ul><li>INNER, LEFT- and RIGHT-OUTER JOIN </li></ul></ul><ul><ul><li>Quantified subqueries </li></ul></ul><ul><li>Supports dot-notation for many-to-one, one-to-one associations, for example: </li></ul>select s.id, s.orderDate, s.region, s.customers.givenName, s.customers.surname from SalesOrders s where s.orderDate between '2001-03-16' and '2001-03-26' and s.region <> 'Central' order by s.orderDate
  • 20. HQL: Hibernate Query Language <ul><li>Hibernate’s HQL supports SELECT, inner and outer JOIN, WHERE, HAVING, simple GROUP BY, UNION, ORDER BY, self-joins with different correlation names </li></ul><ul><li>HQL does not support recursion, common table expressions, window functions, derived tables, other set operators, table functions, array or structured types, APPLY/OUTER APPLY, CROSS JOIN, GROUP BY CUBE/ROLLUP/GROUPING SETS, FULL OUTER JOIN </li></ul>select distinct c.givenName from Customers c left join c.salesOrderses where c.city in (select c2.city from Customers c2 where c2.companyName like '%Power%')
  • 21. HQL: Hibernate Query Language <ul><li>HQL is augmented by “dialects” that implement specific methods to modify the SQL generated by Hibernate before execution on the server </li></ul><ul><li>HQL has optional support for (implemented by a specific dialect): </li></ul><ul><ul><li>UNION ALL (for entity-type hierarchies) </li></ul></ul><ul><ul><li>LIMIT (SELECT TOP N), OFFSET </li></ul></ul><ul><ul><li>IDENTITY, GUID data types </li></ul></ul><ul><ul><li>Syntax to declare an updateable cursor and locking mode </li></ul></ul><ul><ul><li>Case-insensitive string comparisons </li></ul></ul>
  • 22. Object persistence in Hibernate <ul><li>Saving objects </li></ul><ul><ul><li>Once an object is created or modified, it must be saved explicitly and then the transaction must be committed: </li></ul></ul><ul><ul><ul><li>session.save(<object name>); </li></ul></ul></ul><ul><ul><ul><li>tx.commit(); </li></ul></ul></ul><ul><li>Loading objects </li></ul><ul><ul><li>The Hibernate session interface offers several load() methods for loading objects into memory from database tuples: </li></ul></ul><ul><ul><ul><li>public Object load(Class theClass, Serializable id) </li></ul></ul></ul><ul><ul><ul><li>public Object load(String entityname, Serializable id) </li></ul></ul></ul><ul><ul><ul><li>public Object load(Object object, Serializable id) </li></ul></ul></ul><ul><ul><li>Other load() methods permit specification of a lock mode, ie Select for Update </li></ul></ul>
  • 23. Object persistence in Hibernate <ul><li>A refresh() method is implemented to reload objects from the database </li></ul><ul><ul><li>Useful for when attributes are modified by database triggers upon INSERT or UPDATE </li></ul></ul><ul><ul><ul><li>Highly error-prone </li></ul></ul></ul><ul><li>Updating objects </li></ul><ul><ul><li>Hibernate manages changes to persistent objects transparently and automatically </li></ul></ul><ul><ul><ul><li>If an attribute is altered, the appropriate Hibernate session will queue the change for writing to the database using SQL </li></ul></ul></ul><ul><ul><ul><li>One can force changes to be written at a certain point using the flush() method, controlled by isDirty() and setFlushMode() </li></ul></ul></ul>
  • 24. Class inheritance <ul><li>Hibernate offers a variety of built-in techniques to handle different normalizations of entity-type hierarchies: </li></ul><ul><ul><li>Single table with discriminator value </li></ul></ul><ul><ul><li>Multiple tables fully normalized into BCNF </li></ul></ul><ul><ul><li>A hybrid model consisting of a mixture of the two </li></ul></ul><ul><li>If represented as different objects in a mapping, an ETH requires careful construction and different equals() and hashcode() implementations </li></ul>
  • 25. FETCH strategies <ul><li>A major pain point is the N+1 SELECTs problem </li></ul><ul><ul><li>Navigation through the object model iteratively causes additional rows to be retrieved from the database, using independent SQL requests </li></ul></ul><ul><ul><ul><li>“ client-side” join; performance tends to be extremely poor due to the additional latency </li></ul></ul></ul><ul><ul><ul><li>Adaptive, client-side prefetching and SQL rewriting may be of benefit in these scenarios: see Ivan Bowman’s PhD thesis on Scalpel </li></ul></ul></ul><ul><ul><li>Alternatively, in the mapping one may specify the selection method: either “lazy” or “eager” </li></ul></ul><ul><ul><ul><li>One must tradeoff this method will global application behaviour, or override it on a case-by-case basis using HQL-specific syntax </li></ul></ul></ul>
  • 26. Concurrency control <ul><li>Hibernate relies on the database’s locking scheme for concurrency control </li></ul><ul><ul><li>ANSI isolation levels 0-3 are supported directly; 1 or 2 is recommended (READ COMMITTED and REPEATABLE READ) </li></ul></ul><ul><ul><ul><li>DBMS that support snapshot isolation require tweaks to their Hibernate dialect implementation </li></ul></ul></ul><ul><ul><li>Lock mode for individual HQL statements or instantiations of objects can be specified directly, ie </li></ul></ul><ul><ul><li>Customer c = (Customer) session.get(Customer.class, 101, LockMode.Upgrade); </li></ul></ul><ul><li>Hibernate has builtin support for optimistic concurrency control </li></ul><ul><ul><li>Can use either version numbers (added to the schema of the table), or base change control on all of the values in the row </li></ul></ul>
  • 27. Caching and concurrency control <ul><li>Like many runtime environments, Hibernate supports built-in caching controls to speed-up database interaction </li></ul><ul><li>Two levels of caching are supported: </li></ul><ul><ul><li>Level 1: Persistence context cache </li></ul></ul><ul><ul><ul><li>Lifespan is a transaction or a conversation without sharing. </li></ul></ul></ul><ul><ul><ul><li>Guarantees scope of the object and object identity. Mandatory. </li></ul></ul></ul><ul><ul><li>Level 2: Pluggable, scope is process or cluster (shared) </li></ul></ul><ul><ul><ul><li>Configurable on a class-by-class basis </li></ul></ul></ul><ul><ul><ul><li>Selectable concurrency control strategies: Transactional, Read-write, non-strict read-write, read-only </li></ul></ul></ul><ul><ul><ul><li>EHCache, OpenSymphony, SwarmCache, JBoss Cache </li></ul></ul></ul>
  • 28. Research opportunities <ul><li>Robust, industrial-strength debugging frameworks </li></ul><ul><ul><li>Identify how a particular database interaction was caused by what specific application program behaviour </li></ul></ul><ul><ul><li>Analysis of concurrency control behaviour to determine application correctness, for example with respect to lost updates </li></ul></ul><ul><li>Identifying common classes of SQL queries for specific sets of optimizations </li></ul><ul><ul><li>Place in the dialect layer, in the DBMS itself, or in a separate tool that can support the optimization of multiple inter-related statements </li></ul></ul><ul><li>Mechanisms to support additional types of mappings and more complex schemas </li></ul><ul><li>Support for recursion </li></ul>
  • 29. Questions? <ul><li>Watch my blog for continuing articles on supporting ORM toolkits with SQL Anywhere </li></ul><ul><li>http://iablog.sybase.com/paulley </li></ul><ul><li>References: </li></ul><ul><li>Christian Bauer and Gavin King (November 2007). Java Persistence with Hibernate (revised edition of Hibernate in Action). Manning Publications, New York, New York. ISBN 1-932394-88-5. Seventh printing. </li></ul><ul><li>Dave Minter and Jeff Linwood (2005) Pro Hibernate 3 . Apress Books, Berkeley, CA. </li></ul><ul><li>ACM Queue 6(3), May/June 2008, “Bridging the Object-Relational Divide”. </li></ul>

×