SlideShare a Scribd company logo
Object/Relational Mapping Solving the structural paradigm mismatch
Creating a Domain Model An object-oriented domain model captures the entities with the help of the business experts concrete things like User, Item, Category, abstract like PricingAlgorithm developers create an  object model  of the problem  domain can be only a mental model or elaborate as UML diagrams we may also have a relational data model, designed using E / R modelling a relational schema, or a model defined in some CASE tool Item 0..* User 0..* sells Category
Our example application CaveatEmptor  is an online auction system – we have the following domain model: Do we need any special programming model to implement this domain model in Java? Item 0..* User 0..* sells Bid 0..* 0..* Address 0..* BillingDetails CreditCard BankAccount home billing 0..* Category
Writing POJOs We implement our domain model persistent classes with POJOs loosely follow the JavaBean specification (actually, just about any Java class will do) we usually provide accessor methods for property management with (any visibility), but this is not required no-argument constructor (with at least  package  visibility) is required better to make the class and all public methods non-final declare the class  Serializable  if you need to transport data between tiers POJO Best Practices are actually requirements of Hibernate for persistent classes.
A simple POJO public class User implements Serializable { private String username; private Address address; public User() {} public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Address getAddress() { return address;} public void setAddress(Address address) { this.address = address; } public MonetaryAmount calcShippingCosts(Address from) { ... } }
Adding logic to accessor methods We can also add certain kinds of logic - especially validation - to our accessor methods: Let’s create the mapping for  User ... public class User { private String firstname; ... public void setFirstname(String firstname) throws InvalidNameException { if ( !StringUtil.isCapitalizedName(firstname) ) throw new InvalidNameException(firstname); this.firstname = firstname; ) ... }
Class mapping We use the  <class>  element for each persistent class requires class name, table and schema are optional by default, all columns are inserted and updated override with dynamic insert and update, no SQL generation on startup <hibernate-mapping package=&quot;org.hibernate.auction.model&quot; schema=&quot;AUCTION&quot;> <class name=&quot;User&quot; table=&quot;USER&quot; dynamic-insert=&quot;true&quot; dynamic-update=&quot;true&quot;> </class> ... </hibernate-mapping>
Property mapping We use  <property>  for each property of our class: If your property and class names are special (prefix, suffix, etc.), implement a Hibernate  NamingStrategy . <!- An immutable property --> <property name=&quot;orderNumber&quot; column=&quot;ORDER_NR&quot; type=&quot;string&quot; not-null=&quot;true&quot; access=&quot;field&quot; update=&quot;false&quot;/> <!-- A derived property (read only) --> <property name=&quot;totalIncludingTax&quot; formula=”PRICE + PRICE * TAX_RATE&quot; type=&quot;big_decimal&quot;/>
Writing persistent classes Entity associations are also represented as properties: 0..* public class Category { private String name; private Category  parentCategory ; private Set  childCategories  = new HashSet(); Set getChildCategories() { return childCategories; } void setChildCategories(Set categories) { childCategories = categories; } public Category getParentCategory() {  return parentCategory(); } void setParentCategory(Category category) { parentCategory = category; } } Category
Optimizing association handling To create an association, we have to set the  parentCategory  of a child the child must be added to the  childCategories  of the parent we don't have some container-managed relationship handling! We will come back to association mappings soon…. public void addChildCategory(Category child) { // Be defensive! if (child == null) throw new IllegalArgumentException(&quot;null Child&quot;); // Ensure multiplicity if ( child.getParent() != null ) child.getParent().getChildCategories().remove(child); child.setParent(this); getChildCategories().add(child); }
Primary keys The primary key for our tables should be unique:  no duplicate values ever constant:  value is never updated required:  never null Types of primary keys: natural key:  an attribute that is unique by virtue of its business meaning (any composite key is a natural key) surrogate key:  an attribute generated by the system, with no meaning to the user, and no business semantics For new systems, we recommend the use of  surrogate keys  everywhere ,  since this strategy makes schema evolution simpler – true natural keys are hard to find!
Database identity in Hibernate We add an  identifier property  to persistent classes the value of that property is the primary key value the name should always be the same for all classes, e.g.  id Should the identifier property be public? if we use the identifier outside of persistence, e.g. in web applications it is a convenient “handle” to a particular instance lookup by identifier is an especially efficient operation in Hibernate we usually have a public getter and a private setter public class Category { private Long id = null; public Long getId() { return this.id; } private void setId(Long id) { this.id = id; } }
Identity mapping Identifier property mappings the identifier property type may be any Hibernate type the identifier generation strategy may be customized identifier properties are actually optional, but  strongly  recommended (if you don’t have an identifier property, just omit  name  in the mapping) <class name=&quot;Category&quot; table=&quot;CATEGORY&quot;> <id name=&quot;id&quot; column=&quot;CATEGORY_ID&quot; type=&quot; long &quot;> <generator class=&quot; native &quot;/> </id> ... </class>
Identifier generation strategies increment incrementing value, unique to the JVM ( long, short, int ) native picks other strategies, depending on the database capabilities ( long, short, int ) identity identity column types in DB2, MS SQL Server, Sybase, MySQL, etc ( long, short, int ) sequence incrementing sequence in DB2, PostgreSQL, Oracle, etc ( long, short, int ) hilo high- and low-value algorithm, unique to database instance ( long, short, int ) uuid.hex Hibernate UUID algorithm, unique to a subnet ( String ) guid database GUID algorithm for MySQL and MS SQL Server, introduced in Hibernate3 ( String ) assigned the application assigns identifier values
Hibernate type system Entity types (e.g.  User ,  Category ,  Item ) own database identity (primary key) references are foreign keys own lifecycle independent of other entities shared references are possible usually user-defined classes Value types (e.g.  Address, String, Integer ) no database identity lifespan of value object is bound to containing entity built-in JDK types and user-defined types
Built-in value types integer, long, short, float, double, character, byte, boolean, yes_no, true_false map Java primitives or wrapper classes string maps  java.lang.String date, time, timestamp mappings for  java.util.Date  and subclasses calendar, calendar_date mappings for  java.util.Calendar big_decimal maps  java.math.BigDecimal locale, timezone, currency, class mappings for miscellaneous JDK classes binary, text mappings for binary (byte array) or text (string) data blob, clob  mappings for  java.sql.Blob, java.sql.Clob serializable maps a serializable Java object to a binary data type – do not use this!
Composition in our object model Classes can have a  composition  relationship: User Address home billing class User { private Long id; private Address homeAddress; private Address billingAddress; } class Address { private String street; private String zipcode; private String city; }
Mapping components We sometimes map the composed object to the same table USER  table with  STREET ,  ZIPCODE ,  CITY  columns <class name=&quot;User&quot; table=&quot; USER &quot;> <id name=&quot;id&quot; column=&quot;USER_ID&quot;> <generator class=&quot;native&quot;/> </id> <component name=&quot;homeAddress&quot; class=&quot;Address&quot;> <property name=&quot;street&quot; column=&quot; HOME_STREET &quot; not-null=&quot;true&quot;/> <property name=&quot;city&quot; column=&quot; HOME_CITY &quot;  not-null=&quot;true&quot;/> <property name=&quot;zipcode&quot; column=&quot; HOME_ZIPCODE &quot; not-null=&quot;true&quot;/> </component> ... </class>
Bidirectional component mapping We can even  make the relationship bidirectional: we can't have shared references to  Address  objects a null  homeAddress  will be represented as  null  values in all columns <component name=&quot;homeAddress&quot; class=&quot;Address&quot;> <parent name=&quot;user&quot;/> <property name=&quot;street&quot; column=&quot; HOME_STREET &quot; not-null=&quot;true&quot;/> <property name=&quot;city&quot; column=&quot; HOME_CITY &quot;  not-null=&quot;true&quot;/> <property name=&quot;zipcode&quot; column=&quot; HOME_ZIPCODE &quot; not-null=&quot;true&quot;/> </component>
Class inheritance hierarchies Three strategies to map an inheritance hierarchy: table per concrete class:  no polymorphism table per class hierarchy:  denormalization and discriminator table per subclass:  using &quot;has a&quot; foreign key relationships BillingDetails CreditCard BankAccount
Table per concrete class mapping polymorphic associations to  BillingDetails  are difficult a query against the superclass is several SELECTs changes to the superclass require multiple table changes no special Hibernate mapping, just  <class> << table >> CREDIT_CARD CREDIT_CARD_ID << PK >> OWNER NUMBER TYPE EXP_DATE << table >> BANK_ACCOUNT BANK_ACCOUNT_ID << PK >> OWNER NUMBER BANK_NAME BANK_SWIFT
Table per class hierarchy note the  type discriminator  column best performance, polymorphic queries and associations subclass columns must be nullable! we use the Hibernate  <subclass>  mapping << table >> BILLING_DETAILS BILLING_DETAILS_ID << PK >> BILLING_TYPE << discriminator >> OWNER NUMBER CREDIT_CARD_TYPE CREDIT_CARD_EXP_DATE BANK_ACCOUNT_NAME BANK_ACCOUNT_SWIFT
Mapping a class hierarchy to a single table <subclass>  elements can be nested mapping strategy has to be used for all classes in the sub-hierarchy <class name=&quot;BillingDetails&quot; table=&quot;BILLING_DETAILS&quot;> <id name=&quot;id&quot; column=&quot;BILLING_DETAILS_ID&quot;> <generator class=&quot;native&quot;/> </id> <discriminator column=&quot;BILLING_TYPE&quot;/> <property name=&quot;name&quot; column=&quot;OWNER&quot;/> ... <subclass name=&quot;CreditCard&quot;  discriminator-value=&quot;CC&quot; > <property name=&quot;type&quot; column=&quot;CREDIT_CARD_TYPE&quot;/> ... </subclass> ... </class>
Table per subclass normalized model polymorphic associations even to particular subclasses we use the Hibernate  <joined-subclass>  mapping << table >> CREDIT_CARD CREDIT_CARD_ID <<PK>> <<FK>> TYPE EXP_DATE << table >> BANK_ACCOUNT BANK_ACCOUNT_ID <<PK>> <<FK>> BANK_NAME BANK_SWIFT << table >> BILLING_DETAILS BILLING_DETAILS_ID <<PK>> OWNER NUMBER
Mapping a joined subclass to normalized tables <joined-subclass>  can be nested, but not  <subclass> difficult to implement by hand ad hoc reporting might be more complex <class name=&quot;BillingDetails&quot; table=&quot;BILLING_DETAILS&quot;> <id name=&quot;id&quot; column=&quot;BILLING_DETAILS_ID&quot;> <generator class=&quot;native&quot;/> </id> <property name=&quot;name&quot; column=&quot;OWNER&quot;/> ... <joined-subclass name=&quot;CreditCard&quot; > <key column=&quot;CREDIT_CARD_ID&quot;/> <property name=&quot;type&quot; column=&quot;CREDIT_CARD_TYPE&quot;/> ... </joined-subclass> ... </class>
Class associations A bidirectional  one-to-many  entity association: Managed associations: a change to one side is immediately reflect on the other side e.g.  bid.setItem(item) executes  item.getBids().add(bid) used with container-managed relationships (CMR) in EJB/CMP POJOs do  not  have automatically managed associations! the common Java semantics apply we have to manually set both &quot;ends&quot; of the &quot;link&quot; Hibernate doesn't interfere with POJO semantics! Item Bid 0..*
The tables of this association mapping << table >> ITEM ITEM_ID <<PK>> NAME PRICE ... << table >> BID BID_ID <<PK>> ITEM_ID <<FK>> AMOUNT ... PRICE NAME ITEM_ID 1 2 3 Bar Foo Baz 2.00 50.00 1.00 ITEM AMOUNT ITEM_ID BID_ID 1 2 3 1 1 2 10.00 20.00 55.00 BID
Mapping a unidirectional association The column  ITEM_ID  is a FK to the PK of the  ITEM  table. class Bid { private Item item; public void setItem(Item i) { this.item = i; } public Item getItem() { return item; } } <class name=&quot;Bid&quot; table=&quot;BID&quot;> ...  <many-to-one name=&quot;item&quot; class=&quot;Item&quot; column=&quot;ITEM_ID&quot; not-null=&quot;true&quot;/> </class>
Making the association bidirectional The key element refers to the  ITEM_ID  column in the  BID  table. class Item { private Set bids = new HashSet(); public void getBids() { return bids; } public void addBid(Bid b) { this.bids.add(b) b.setItem(this) // Manage association! } } <class name=&quot;Item&quot; table=&quot;ITEM&quot;> ...  <set name=&quot;bids&quot;> <key column=&quot;ITEM_ID&quot;/> <one-to-many class=&quot;Bid&quot;/> </set> </class>
The big problem We have referenced the ITEM_ID in two mappings At runtime, we have two in-memory representations of this associtaion, the  item  property of the  Bid  and the  bids  of the  Item . Suppose we modify this association: Hibernate does not transparently detect the fact that the two changes refer to the same database column, since at this point we have done nothing to indicate that this is a bidirectional association. item.getBids().add(newBid); newBid.setItem(item);
Making the association bidirectional We have to declare one end as  inverse: changes to the inverse end will be ignored! without  inverse=“true” , Hibernate would try to issue  two  UPDATE statements <class name=&quot;Item&quot; table=&quot;ITEM&quot;> ...  <set name=&quot;bids&quot;  inverse=&quot;true&quot; > <key column=&quot;ITEM_ID&quot;/> <one-to-many class=&quot;Bid&quot;/> </set> </class>
Mapping collections vs Java collections Persists an unordered,non-unique many-to-many collection using a surrogate key. java.util.List idbag Persists an indexed, non-unique collection of primitive values N/A primitive-array Persists an indexed, non-unique collection of values or objects N/A array Persists an unordered, non-unique collection of values or objects java.util.List bag Persists an ordered,non-unique collection of values or objects java.util.List list Persists a collection of key/value pairs java.util.Map map Persists an unordered,unique collection of values or objects java.util.Set set Description Java Collection Type Hibernate Collection Type
One-to-many association <hibernate-mapping package=“demo”> <class name=“Event”  table=“events”> … . <set name=“speakers”> <key column=“event_id”/> <one-to-many  class=“Speaker”/> </set> <set name=“attendees”> <key column=“event_id”/> <one-to-many  class=“Attendee”/> </set> … . </class> </hibernate-mapping> public class Event { private Set speakers; private set attendees; public void setSpeakers(Set speakers) { this.speakers=speakers;} public set getSpeakers() {return this.speakers;} public void setAttendees(Set attendees) { this.attendees=attendees;} public set getAttendees() {return this.attendees;}
One-to-many events events events attendees id bigint(pk) id bigint (pk) event_id bigint (fk) A one-to-many association from events to attendees
Many-to-many Suppose Attendees can attend more than one Event. This is a  Many-to-many mapping for the set of Attendees: <set name=“attendees”  table=“event_attendees”> <key column=“event_id”> <many-to-many column=“attendee_id”  class=“Attendee”/> </set>
many-to-many events events events event_attendees id bigint(pk) event_id bigint (fk) attendee_id bigint (fk) A many-to-many table schema from events to attendees events events attendees id bigint(pk)
Persisting collections of values The below mapping definition for a persistent set of Integers  <set name=“ratings”  table=“event_ratings”> <key column=“event_id”/> <element column=“rating” type=“integer” </set> The table attribute defines the event_ratings table, which is  Used to store the values.
Lists Unlike Set, Lists can contain duplicate elements. Since Lists are Indexed, meaning that contained elements are stored at a specific Location in the List, you need to define a <list-index> element: <list name=“speaker”> <list-index  column=“speaker_index”/> <key column = “event_id”/> <one-to-many  class=“Speaker”/> </list>
Maps Maps store entries in key/value pairs, meaning that we retrieve the Value by looking up the associated key. <map name=“speakers”> <map-key  column=“speakers_index” type=“string”  length=“20”/> <key column=“event_id”/> <one-to-many  class=“speaker”/> </map> Inserting elements into the map, use a String for the key Map speakers = new HashMap(); speakers.put(“speakers1”, new Speaker()); speakers.put(“speakers2”,new Speaker()); Event event = new Event(); event.setSpeakers(speakers);
Bags To store a collection of objects without worrying about ordering Or duplicate elements. This is where Bags come in : <bag  name=“speakers”> <key column=“event_id”/> <one-to-many  class=“Speaker”/> </bag> For the javabean’s perspective, the collection of Speakers is a List. Import java.util.List; Public class Event { Private List speakers; Public void setSpeakers(List speakers) { this.speakers = speakers;} Public List getSpeakers() { return this.speakers;} } However, using a Bag for Hibernate means you don’t need to explicitly create an index column. Set and Bag both doesn’t require an index column, but remember that a Set can’t contain duplicate elements, whereas Bags can
idbags Suppose we have a many-to-many association between Events and Speakers. Speakers can belong to the same Event multiple times, so we can’t use a Set. We also need to ensure fast and efficient access to the many-to-many table event_speakers. We really need to be able to assign a primary key to the event_speakers table. This is where idbags come in: <idbag  name=“speakers”  table=“event_speakers” lazy=“true”  cascade=“all”> <collection-id  type=“long”  column=“event_speakers_id”> <generator-class=“native”/> </collection-id> <key column=“event_id”/> <many-to-many  class=“Speaker”  column=“speaker_id”/> </idbag>
idbags events events events event_attendees id bigint(pk) event_id bigint  speaker_id bigint  events events speakers id bigint(pk) event_speaker_id bigint (PK)
Lazy collections A lazy collection is populated on demand. It means that the collection of entity objects or values is populated only when the application accesses the collection.  Populating the collection happens transparently when the collection is first accessed. Why lazy collections? A collection of objects can possibly contain hundreds or thousands of objects, and the application may not need to access the collection immediately, or at all. Loading hundreds of persistent objects for no reason will certainly impact application performance. It’s better to populate the persistent collection only when it is needed.
Lazy collections – Session closed problem To populate a lazy collection, the same Session instance used to retrieve the persistent object from the database must be open when the collection is populated. The following code is incorrectly attempts to load the collection of attendees for an Event after the Session has been closed: Session session =factory.openSession(); Event event = session.get(Event.class,eventId); Session.close(); Set attendees = event.getAttendees();
Lazy collections – correct method Session session =factory.openSession(); Event event = session.get(Event.class,eventId); Set attendees = event.getAttendees(); Session.close(); Persistent collections are lazy by default in Hibernate 3. For non-lazy collections, you must explicitly declare them as lazy=“false” in the mapping definition. For example: <set name=“attendees”  lazy=“false”> <key column=“event_id”/> <one-to-many class=“Attendee”/> </set>
Lazy collections – multitier problems Any collection, including collections of values and arrays, can be declared not to be “lazy’. The problem with lazy collections in populating them in a multitier application, such as web application,where keeping the Session open can be tricky. Solution :  The only requirement is that a Hibernate Session must Be available in the view tier, which is possible when you use a servlet filter or spring to manage your Session instances.
Sorted Collections A common requirement when dealing with collection is to sort them According to some criteria. The sorting criteria can be fixed or arbitrary, depending on application requirements. Hibernate supports sorting sets,maps and bags. <set name=“attendees”  order-by=“last_name”> <key column=“event_id”/> <one-to-many  class=“Attendee”/> </set> few more examples: ordery-by = “last_name, first_name” order_by = “last_name, first_name asc” Use Filter to a collection Set sortedAttendees =  session.filter(event.getAttendees(), “ order by this.phoneNumber”);
Filters Filters allow you to apply filtering criteria to returned objects at the Session level. You can pass parameters to filters, and they work with classes or collections.  To use filters, you first define them in the mapping files, and then enable a given filter by name when using the Session object. <hibernate-mapping> <filter-def  name=“nameFilter”> <filter-param name=“nameFilterParam”  type=“string”/> </fliter-def> </hibernate-mapping>
Filters - 2 With the filter defined, we can apply it to persistent classes and colections : <class name = “Event”> <filter name=“nameFilter” condition = “:nameFilterParam=name”/> <set name=“attendees”> <filter name=“nameFilter” condition = “:nameFilterParam = last_name”/> </set> </class>
Filters - 3 This code applies the filter to the name column in the events table, and to the last_name column in the attendees table. To apply the filters, we must explicitly enable them at the Session level ; Filter  f  = session.enablefilter(“nameFilter”); f.setParameter(“nameFilterParam”, “Plenary”); List results = session.createQuery(“from Event”).list(); This code enables the named filter ant then sets the filter parameter. This results will only contain instances of Event with the name Plenary. We can also enable multiple filters per session.
Metadata alternatives Attribute-oriented  metadata JSR-175 annotations support, coming soon! XDoclet Hibernate module Hibernate mapping metadata can be manipulated programmatically we can use dom4j or JDOM to generate mapping files in memory we can manipulate the Hibernate  Configuration  metamodel directly let's demonstrate this my adding a property to a mapped class… /** * @hibernate.class *  table=&quot;CATEGORY&quot; */ public class Category { ... /** * @hibernate.property */ public String getName() { return name; } ... }
Adding a property at runtime // Get the existing mapping for User from Configuration PersistentClass userMapping = cfg .getClassMapping(User.class); // Define a new column for the USER table Column column = new Column(); userMapping.getTable().addColumn(column); // Wrap the column in a Value SimpleValue value = new SimpleValue(); value.setTable( userMapping.getTable() ); value.addColumn(column); // Define a new property of the User class Property prop = new Property(); prop.setValue(value); prop.setName(&quot;motto&quot;); userMapping.addProperty(prop); // Build a new session factory, using the new mapping SessionFactory sf =  cfg.buildSessionFactory();
Reading metadata at runtime There is also the  runtime metamodel , exposed via the  SessionFactory : Category category = ...; ClassMetadata meta = sessionFactory.getClassMetadata(Category.class); String[] metaPropertyNames = meta.getPropertyNames(); Object[] propertyValues = meta.getPropertyValues(category);

More Related Content

PDF
Hibernate Mapping
PDF
Java Persistence API 2.0: An Overview
PPT
Java căn bản - Chapter4
PDF
Kick Start Jpa
DOCX
Computer Programming 2
PPTX
Vb ch 3-object-oriented_fundamentals_in_vb.net
PPTX
Android App code starter
PPT
Ap Power Point Chpt7
Hibernate Mapping
Java Persistence API 2.0: An Overview
Java căn bản - Chapter4
Kick Start Jpa
Computer Programming 2
Vb ch 3-object-oriented_fundamentals_in_vb.net
Android App code starter
Ap Power Point Chpt7

What's hot (19)

PPTX
Lab 4
PPTX
Object Oriended Programming with Java
PDF
Java Persistence API
PPT
object oriented programming language by c++
PPTX
Lecture 5
PPTX
Objects and Types C#
PPT
Advanced c#
PPTX
Classes objects in java
PDF
Xm Lquickref
PDF
Xml Syntax Quick Reference
ODP
Beginners Guide to Object Orientation in PHP
PDF
Class and object in C++ By Pawan Thakur
PDF
How to write you first class in c++ object oriented programming
PPTX
Object oreinted php | OOPs
PPTX
Esoteric LINQ and Structural Madness
PPTX
Object Oriented Programming Basics with PHP
PDF
Model Inheritance
PPSX
Oop features java presentationshow
Lab 4
Object Oriended Programming with Java
Java Persistence API
object oriented programming language by c++
Lecture 5
Objects and Types C#
Advanced c#
Classes objects in java
Xm Lquickref
Xml Syntax Quick Reference
Beginners Guide to Object Orientation in PHP
Class and object in C++ By Pawan Thakur
How to write you first class in c++ object oriented programming
Object oreinted php | OOPs
Esoteric LINQ and Structural Madness
Object Oriented Programming Basics with PHP
Model Inheritance
Oop features java presentationshow
Ad

Viewers also liked (17)

PPT
Ling to SQL and Entity Framework performance analysis
PPTX
ORM을 활용할 경우의 설계, 개발 과정
PPT
Object Relational Mapping In Real World Applications
ODP
What's new, what's hot in PHP 5.3
PDF
QnA blog using Django - ORM, 회원가입, 로그인/로그아웃
PDF
좌충우돌 ORM 개발기 2012 DAUM DEVON
KEY
Object Relational Mapping in PHP
PDF
ORM: Object-relational mapping
PPTX
JDXA, The KISS ORM for Android
PPTX
L16 Object Relational Mapping and NoSQL
PDF
좌충우돌 ORM 개발기 | Devon 2012
PDF
About Orm.fm
PPTX
Object-Relational Mapping and Dependency Injection
PDF
L18 Object Relational Mapping
PDF
Automated functional size measurement for three tier object relational mappin...
PPTX
기술적 변화를 이끌어가기
PDF
SK플래닛_README_마이크로서비스 아키텍처로 개발하기
Ling to SQL and Entity Framework performance analysis
ORM을 활용할 경우의 설계, 개발 과정
Object Relational Mapping In Real World Applications
What's new, what's hot in PHP 5.3
QnA blog using Django - ORM, 회원가입, 로그인/로그아웃
좌충우돌 ORM 개발기 2012 DAUM DEVON
Object Relational Mapping in PHP
ORM: Object-relational mapping
JDXA, The KISS ORM for Android
L16 Object Relational Mapping and NoSQL
좌충우돌 ORM 개발기 | Devon 2012
About Orm.fm
Object-Relational Mapping and Dependency Injection
L18 Object Relational Mapping
Automated functional size measurement for three tier object relational mappin...
기술적 변화를 이끌어가기
SK플래닛_README_마이크로서비스 아키텍처로 개발하기
Ad

Similar to 03 Object Relational Mapping (20)

PPT
Persisting Your Objects In The Database World @ AlphaCSP Professional OSS Con...
ODP
Java Persistence API
PDF
Persistence
PDF
ActiveJDBC - ActiveRecord implementation in Java
PPT
PPT
01 Persistence And Orm
PDF
JPA and Hibernate
PDF
PPT
04 Data Access
PDF
Jpa Online Final
ODP
JavaEE Spring Seam
PDF
Java persistence api 2.1
PPT
Hibernate Session 2
PPT
Spring data
PDF
PDF
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
PPT
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.ppt
PDF
Mapping objects to_relational_databases
PPT
Mapping inheritance structures_mapping_class
PDF
S313431 JPA 2.0 Overview
Persisting Your Objects In The Database World @ AlphaCSP Professional OSS Con...
Java Persistence API
Persistence
ActiveJDBC - ActiveRecord implementation in Java
01 Persistence And Orm
JPA and Hibernate
04 Data Access
Jpa Online Final
JavaEE Spring Seam
Java persistence api 2.1
Hibernate Session 2
Spring data
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.ppt
Mapping objects to_relational_databases
Mapping inheritance structures_mapping_class
S313431 JPA 2.0 Overview

More from Ranjan Kumar (20)

PPT
Introduction to java ee
PPT
Fantastic life views ons
PPS
Lessons on Life
PPS
Story does not End here
PPS
Whata Split Second Looks Like
PPS
Friendship so Sweet
PPS
Dedicate Time
PPS
Paradise on Earth
PPS
Bolivian Highway
PPS
Chinese Proverb
PPS
Warren Buffet
PPS
Dear Son Dear Daughter
PPS
Jara Sochiye
PPS
Blue Beauty
PPS
Alaska Railway Routes
PPS
Poison that Kills the Dreams
PPS
Horrible Jobs
PPS
Best Aviation Photography
PPSX
Role of Attitude
PPS
45 Lesons in Life
Introduction to java ee
Fantastic life views ons
Lessons on Life
Story does not End here
Whata Split Second Looks Like
Friendship so Sweet
Dedicate Time
Paradise on Earth
Bolivian Highway
Chinese Proverb
Warren Buffet
Dear Son Dear Daughter
Jara Sochiye
Blue Beauty
Alaska Railway Routes
Poison that Kills the Dreams
Horrible Jobs
Best Aviation Photography
Role of Attitude
45 Lesons in Life

Recently uploaded (20)

PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
Big Data Technologies - Introduction.pptx
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Encapsulation theory and applications.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
Cloud computing and distributed systems.
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Big Data Technologies - Introduction.pptx
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
Mobile App Security Testing_ A Comprehensive Guide.pdf
Machine learning based COVID-19 study performance prediction
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Per capita expenditure prediction using model stacking based on satellite ima...
Encapsulation theory and applications.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Review of recent advances in non-invasive hemoglobin estimation
MYSQL Presentation for SQL database connectivity
20250228 LYD VKU AI Blended-Learning.pptx
Chapter 3 Spatial Domain Image Processing.pdf
Cloud computing and distributed systems.
Diabetes mellitus diagnosis method based random forest with bat algorithm
Reach Out and Touch Someone: Haptics and Empathic Computing
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...

03 Object Relational Mapping

  • 1. Object/Relational Mapping Solving the structural paradigm mismatch
  • 2. Creating a Domain Model An object-oriented domain model captures the entities with the help of the business experts concrete things like User, Item, Category, abstract like PricingAlgorithm developers create an object model of the problem domain can be only a mental model or elaborate as UML diagrams we may also have a relational data model, designed using E / R modelling a relational schema, or a model defined in some CASE tool Item 0..* User 0..* sells Category
  • 3. Our example application CaveatEmptor is an online auction system – we have the following domain model: Do we need any special programming model to implement this domain model in Java? Item 0..* User 0..* sells Bid 0..* 0..* Address 0..* BillingDetails CreditCard BankAccount home billing 0..* Category
  • 4. Writing POJOs We implement our domain model persistent classes with POJOs loosely follow the JavaBean specification (actually, just about any Java class will do) we usually provide accessor methods for property management with (any visibility), but this is not required no-argument constructor (with at least package visibility) is required better to make the class and all public methods non-final declare the class Serializable if you need to transport data between tiers POJO Best Practices are actually requirements of Hibernate for persistent classes.
  • 5. A simple POJO public class User implements Serializable { private String username; private Address address; public User() {} public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Address getAddress() { return address;} public void setAddress(Address address) { this.address = address; } public MonetaryAmount calcShippingCosts(Address from) { ... } }
  • 6. Adding logic to accessor methods We can also add certain kinds of logic - especially validation - to our accessor methods: Let’s create the mapping for User ... public class User { private String firstname; ... public void setFirstname(String firstname) throws InvalidNameException { if ( !StringUtil.isCapitalizedName(firstname) ) throw new InvalidNameException(firstname); this.firstname = firstname; ) ... }
  • 7. Class mapping We use the <class> element for each persistent class requires class name, table and schema are optional by default, all columns are inserted and updated override with dynamic insert and update, no SQL generation on startup <hibernate-mapping package=&quot;org.hibernate.auction.model&quot; schema=&quot;AUCTION&quot;> <class name=&quot;User&quot; table=&quot;USER&quot; dynamic-insert=&quot;true&quot; dynamic-update=&quot;true&quot;> </class> ... </hibernate-mapping>
  • 8. Property mapping We use <property> for each property of our class: If your property and class names are special (prefix, suffix, etc.), implement a Hibernate NamingStrategy . <!- An immutable property --> <property name=&quot;orderNumber&quot; column=&quot;ORDER_NR&quot; type=&quot;string&quot; not-null=&quot;true&quot; access=&quot;field&quot; update=&quot;false&quot;/> <!-- A derived property (read only) --> <property name=&quot;totalIncludingTax&quot; formula=”PRICE + PRICE * TAX_RATE&quot; type=&quot;big_decimal&quot;/>
  • 9. Writing persistent classes Entity associations are also represented as properties: 0..* public class Category { private String name; private Category parentCategory ; private Set childCategories = new HashSet(); Set getChildCategories() { return childCategories; } void setChildCategories(Set categories) { childCategories = categories; } public Category getParentCategory() { return parentCategory(); } void setParentCategory(Category category) { parentCategory = category; } } Category
  • 10. Optimizing association handling To create an association, we have to set the parentCategory of a child the child must be added to the childCategories of the parent we don't have some container-managed relationship handling! We will come back to association mappings soon…. public void addChildCategory(Category child) { // Be defensive! if (child == null) throw new IllegalArgumentException(&quot;null Child&quot;); // Ensure multiplicity if ( child.getParent() != null ) child.getParent().getChildCategories().remove(child); child.setParent(this); getChildCategories().add(child); }
  • 11. Primary keys The primary key for our tables should be unique: no duplicate values ever constant: value is never updated required: never null Types of primary keys: natural key: an attribute that is unique by virtue of its business meaning (any composite key is a natural key) surrogate key: an attribute generated by the system, with no meaning to the user, and no business semantics For new systems, we recommend the use of surrogate keys everywhere , since this strategy makes schema evolution simpler – true natural keys are hard to find!
  • 12. Database identity in Hibernate We add an identifier property to persistent classes the value of that property is the primary key value the name should always be the same for all classes, e.g. id Should the identifier property be public? if we use the identifier outside of persistence, e.g. in web applications it is a convenient “handle” to a particular instance lookup by identifier is an especially efficient operation in Hibernate we usually have a public getter and a private setter public class Category { private Long id = null; public Long getId() { return this.id; } private void setId(Long id) { this.id = id; } }
  • 13. Identity mapping Identifier property mappings the identifier property type may be any Hibernate type the identifier generation strategy may be customized identifier properties are actually optional, but strongly recommended (if you don’t have an identifier property, just omit name in the mapping) <class name=&quot;Category&quot; table=&quot;CATEGORY&quot;> <id name=&quot;id&quot; column=&quot;CATEGORY_ID&quot; type=&quot; long &quot;> <generator class=&quot; native &quot;/> </id> ... </class>
  • 14. Identifier generation strategies increment incrementing value, unique to the JVM ( long, short, int ) native picks other strategies, depending on the database capabilities ( long, short, int ) identity identity column types in DB2, MS SQL Server, Sybase, MySQL, etc ( long, short, int ) sequence incrementing sequence in DB2, PostgreSQL, Oracle, etc ( long, short, int ) hilo high- and low-value algorithm, unique to database instance ( long, short, int ) uuid.hex Hibernate UUID algorithm, unique to a subnet ( String ) guid database GUID algorithm for MySQL and MS SQL Server, introduced in Hibernate3 ( String ) assigned the application assigns identifier values
  • 15. Hibernate type system Entity types (e.g. User , Category , Item ) own database identity (primary key) references are foreign keys own lifecycle independent of other entities shared references are possible usually user-defined classes Value types (e.g. Address, String, Integer ) no database identity lifespan of value object is bound to containing entity built-in JDK types and user-defined types
  • 16. Built-in value types integer, long, short, float, double, character, byte, boolean, yes_no, true_false map Java primitives or wrapper classes string maps java.lang.String date, time, timestamp mappings for java.util.Date and subclasses calendar, calendar_date mappings for java.util.Calendar big_decimal maps java.math.BigDecimal locale, timezone, currency, class mappings for miscellaneous JDK classes binary, text mappings for binary (byte array) or text (string) data blob, clob mappings for java.sql.Blob, java.sql.Clob serializable maps a serializable Java object to a binary data type – do not use this!
  • 17. Composition in our object model Classes can have a composition relationship: User Address home billing class User { private Long id; private Address homeAddress; private Address billingAddress; } class Address { private String street; private String zipcode; private String city; }
  • 18. Mapping components We sometimes map the composed object to the same table USER table with STREET , ZIPCODE , CITY columns <class name=&quot;User&quot; table=&quot; USER &quot;> <id name=&quot;id&quot; column=&quot;USER_ID&quot;> <generator class=&quot;native&quot;/> </id> <component name=&quot;homeAddress&quot; class=&quot;Address&quot;> <property name=&quot;street&quot; column=&quot; HOME_STREET &quot; not-null=&quot;true&quot;/> <property name=&quot;city&quot; column=&quot; HOME_CITY &quot; not-null=&quot;true&quot;/> <property name=&quot;zipcode&quot; column=&quot; HOME_ZIPCODE &quot; not-null=&quot;true&quot;/> </component> ... </class>
  • 19. Bidirectional component mapping We can even make the relationship bidirectional: we can't have shared references to Address objects a null homeAddress will be represented as null values in all columns <component name=&quot;homeAddress&quot; class=&quot;Address&quot;> <parent name=&quot;user&quot;/> <property name=&quot;street&quot; column=&quot; HOME_STREET &quot; not-null=&quot;true&quot;/> <property name=&quot;city&quot; column=&quot; HOME_CITY &quot; not-null=&quot;true&quot;/> <property name=&quot;zipcode&quot; column=&quot; HOME_ZIPCODE &quot; not-null=&quot;true&quot;/> </component>
  • 20. Class inheritance hierarchies Three strategies to map an inheritance hierarchy: table per concrete class: no polymorphism table per class hierarchy: denormalization and discriminator table per subclass: using &quot;has a&quot; foreign key relationships BillingDetails CreditCard BankAccount
  • 21. Table per concrete class mapping polymorphic associations to BillingDetails are difficult a query against the superclass is several SELECTs changes to the superclass require multiple table changes no special Hibernate mapping, just <class> << table >> CREDIT_CARD CREDIT_CARD_ID << PK >> OWNER NUMBER TYPE EXP_DATE << table >> BANK_ACCOUNT BANK_ACCOUNT_ID << PK >> OWNER NUMBER BANK_NAME BANK_SWIFT
  • 22. Table per class hierarchy note the type discriminator column best performance, polymorphic queries and associations subclass columns must be nullable! we use the Hibernate <subclass> mapping << table >> BILLING_DETAILS BILLING_DETAILS_ID << PK >> BILLING_TYPE << discriminator >> OWNER NUMBER CREDIT_CARD_TYPE CREDIT_CARD_EXP_DATE BANK_ACCOUNT_NAME BANK_ACCOUNT_SWIFT
  • 23. Mapping a class hierarchy to a single table <subclass> elements can be nested mapping strategy has to be used for all classes in the sub-hierarchy <class name=&quot;BillingDetails&quot; table=&quot;BILLING_DETAILS&quot;> <id name=&quot;id&quot; column=&quot;BILLING_DETAILS_ID&quot;> <generator class=&quot;native&quot;/> </id> <discriminator column=&quot;BILLING_TYPE&quot;/> <property name=&quot;name&quot; column=&quot;OWNER&quot;/> ... <subclass name=&quot;CreditCard&quot; discriminator-value=&quot;CC&quot; > <property name=&quot;type&quot; column=&quot;CREDIT_CARD_TYPE&quot;/> ... </subclass> ... </class>
  • 24. Table per subclass normalized model polymorphic associations even to particular subclasses we use the Hibernate <joined-subclass> mapping << table >> CREDIT_CARD CREDIT_CARD_ID <<PK>> <<FK>> TYPE EXP_DATE << table >> BANK_ACCOUNT BANK_ACCOUNT_ID <<PK>> <<FK>> BANK_NAME BANK_SWIFT << table >> BILLING_DETAILS BILLING_DETAILS_ID <<PK>> OWNER NUMBER
  • 25. Mapping a joined subclass to normalized tables <joined-subclass> can be nested, but not <subclass> difficult to implement by hand ad hoc reporting might be more complex <class name=&quot;BillingDetails&quot; table=&quot;BILLING_DETAILS&quot;> <id name=&quot;id&quot; column=&quot;BILLING_DETAILS_ID&quot;> <generator class=&quot;native&quot;/> </id> <property name=&quot;name&quot; column=&quot;OWNER&quot;/> ... <joined-subclass name=&quot;CreditCard&quot; > <key column=&quot;CREDIT_CARD_ID&quot;/> <property name=&quot;type&quot; column=&quot;CREDIT_CARD_TYPE&quot;/> ... </joined-subclass> ... </class>
  • 26. Class associations A bidirectional one-to-many entity association: Managed associations: a change to one side is immediately reflect on the other side e.g. bid.setItem(item) executes item.getBids().add(bid) used with container-managed relationships (CMR) in EJB/CMP POJOs do not have automatically managed associations! the common Java semantics apply we have to manually set both &quot;ends&quot; of the &quot;link&quot; Hibernate doesn't interfere with POJO semantics! Item Bid 0..*
  • 27. The tables of this association mapping << table >> ITEM ITEM_ID <<PK>> NAME PRICE ... << table >> BID BID_ID <<PK>> ITEM_ID <<FK>> AMOUNT ... PRICE NAME ITEM_ID 1 2 3 Bar Foo Baz 2.00 50.00 1.00 ITEM AMOUNT ITEM_ID BID_ID 1 2 3 1 1 2 10.00 20.00 55.00 BID
  • 28. Mapping a unidirectional association The column ITEM_ID is a FK to the PK of the ITEM table. class Bid { private Item item; public void setItem(Item i) { this.item = i; } public Item getItem() { return item; } } <class name=&quot;Bid&quot; table=&quot;BID&quot;> ... <many-to-one name=&quot;item&quot; class=&quot;Item&quot; column=&quot;ITEM_ID&quot; not-null=&quot;true&quot;/> </class>
  • 29. Making the association bidirectional The key element refers to the ITEM_ID column in the BID table. class Item { private Set bids = new HashSet(); public void getBids() { return bids; } public void addBid(Bid b) { this.bids.add(b) b.setItem(this) // Manage association! } } <class name=&quot;Item&quot; table=&quot;ITEM&quot;> ... <set name=&quot;bids&quot;> <key column=&quot;ITEM_ID&quot;/> <one-to-many class=&quot;Bid&quot;/> </set> </class>
  • 30. The big problem We have referenced the ITEM_ID in two mappings At runtime, we have two in-memory representations of this associtaion, the item property of the Bid and the bids of the Item . Suppose we modify this association: Hibernate does not transparently detect the fact that the two changes refer to the same database column, since at this point we have done nothing to indicate that this is a bidirectional association. item.getBids().add(newBid); newBid.setItem(item);
  • 31. Making the association bidirectional We have to declare one end as inverse: changes to the inverse end will be ignored! without inverse=“true” , Hibernate would try to issue two UPDATE statements <class name=&quot;Item&quot; table=&quot;ITEM&quot;> ... <set name=&quot;bids&quot; inverse=&quot;true&quot; > <key column=&quot;ITEM_ID&quot;/> <one-to-many class=&quot;Bid&quot;/> </set> </class>
  • 32. Mapping collections vs Java collections Persists an unordered,non-unique many-to-many collection using a surrogate key. java.util.List idbag Persists an indexed, non-unique collection of primitive values N/A primitive-array Persists an indexed, non-unique collection of values or objects N/A array Persists an unordered, non-unique collection of values or objects java.util.List bag Persists an ordered,non-unique collection of values or objects java.util.List list Persists a collection of key/value pairs java.util.Map map Persists an unordered,unique collection of values or objects java.util.Set set Description Java Collection Type Hibernate Collection Type
  • 33. One-to-many association <hibernate-mapping package=“demo”> <class name=“Event” table=“events”> … . <set name=“speakers”> <key column=“event_id”/> <one-to-many class=“Speaker”/> </set> <set name=“attendees”> <key column=“event_id”/> <one-to-many class=“Attendee”/> </set> … . </class> </hibernate-mapping> public class Event { private Set speakers; private set attendees; public void setSpeakers(Set speakers) { this.speakers=speakers;} public set getSpeakers() {return this.speakers;} public void setAttendees(Set attendees) { this.attendees=attendees;} public set getAttendees() {return this.attendees;}
  • 34. One-to-many events events events attendees id bigint(pk) id bigint (pk) event_id bigint (fk) A one-to-many association from events to attendees
  • 35. Many-to-many Suppose Attendees can attend more than one Event. This is a Many-to-many mapping for the set of Attendees: <set name=“attendees” table=“event_attendees”> <key column=“event_id”> <many-to-many column=“attendee_id” class=“Attendee”/> </set>
  • 36. many-to-many events events events event_attendees id bigint(pk) event_id bigint (fk) attendee_id bigint (fk) A many-to-many table schema from events to attendees events events attendees id bigint(pk)
  • 37. Persisting collections of values The below mapping definition for a persistent set of Integers <set name=“ratings” table=“event_ratings”> <key column=“event_id”/> <element column=“rating” type=“integer” </set> The table attribute defines the event_ratings table, which is Used to store the values.
  • 38. Lists Unlike Set, Lists can contain duplicate elements. Since Lists are Indexed, meaning that contained elements are stored at a specific Location in the List, you need to define a <list-index> element: <list name=“speaker”> <list-index column=“speaker_index”/> <key column = “event_id”/> <one-to-many class=“Speaker”/> </list>
  • 39. Maps Maps store entries in key/value pairs, meaning that we retrieve the Value by looking up the associated key. <map name=“speakers”> <map-key column=“speakers_index” type=“string” length=“20”/> <key column=“event_id”/> <one-to-many class=“speaker”/> </map> Inserting elements into the map, use a String for the key Map speakers = new HashMap(); speakers.put(“speakers1”, new Speaker()); speakers.put(“speakers2”,new Speaker()); Event event = new Event(); event.setSpeakers(speakers);
  • 40. Bags To store a collection of objects without worrying about ordering Or duplicate elements. This is where Bags come in : <bag name=“speakers”> <key column=“event_id”/> <one-to-many class=“Speaker”/> </bag> For the javabean’s perspective, the collection of Speakers is a List. Import java.util.List; Public class Event { Private List speakers; Public void setSpeakers(List speakers) { this.speakers = speakers;} Public List getSpeakers() { return this.speakers;} } However, using a Bag for Hibernate means you don’t need to explicitly create an index column. Set and Bag both doesn’t require an index column, but remember that a Set can’t contain duplicate elements, whereas Bags can
  • 41. idbags Suppose we have a many-to-many association between Events and Speakers. Speakers can belong to the same Event multiple times, so we can’t use a Set. We also need to ensure fast and efficient access to the many-to-many table event_speakers. We really need to be able to assign a primary key to the event_speakers table. This is where idbags come in: <idbag name=“speakers” table=“event_speakers” lazy=“true” cascade=“all”> <collection-id type=“long” column=“event_speakers_id”> <generator-class=“native”/> </collection-id> <key column=“event_id”/> <many-to-many class=“Speaker” column=“speaker_id”/> </idbag>
  • 42. idbags events events events event_attendees id bigint(pk) event_id bigint speaker_id bigint events events speakers id bigint(pk) event_speaker_id bigint (PK)
  • 43. Lazy collections A lazy collection is populated on demand. It means that the collection of entity objects or values is populated only when the application accesses the collection. Populating the collection happens transparently when the collection is first accessed. Why lazy collections? A collection of objects can possibly contain hundreds or thousands of objects, and the application may not need to access the collection immediately, or at all. Loading hundreds of persistent objects for no reason will certainly impact application performance. It’s better to populate the persistent collection only when it is needed.
  • 44. Lazy collections – Session closed problem To populate a lazy collection, the same Session instance used to retrieve the persistent object from the database must be open when the collection is populated. The following code is incorrectly attempts to load the collection of attendees for an Event after the Session has been closed: Session session =factory.openSession(); Event event = session.get(Event.class,eventId); Session.close(); Set attendees = event.getAttendees();
  • 45. Lazy collections – correct method Session session =factory.openSession(); Event event = session.get(Event.class,eventId); Set attendees = event.getAttendees(); Session.close(); Persistent collections are lazy by default in Hibernate 3. For non-lazy collections, you must explicitly declare them as lazy=“false” in the mapping definition. For example: <set name=“attendees” lazy=“false”> <key column=“event_id”/> <one-to-many class=“Attendee”/> </set>
  • 46. Lazy collections – multitier problems Any collection, including collections of values and arrays, can be declared not to be “lazy’. The problem with lazy collections in populating them in a multitier application, such as web application,where keeping the Session open can be tricky. Solution : The only requirement is that a Hibernate Session must Be available in the view tier, which is possible when you use a servlet filter or spring to manage your Session instances.
  • 47. Sorted Collections A common requirement when dealing with collection is to sort them According to some criteria. The sorting criteria can be fixed or arbitrary, depending on application requirements. Hibernate supports sorting sets,maps and bags. <set name=“attendees” order-by=“last_name”> <key column=“event_id”/> <one-to-many class=“Attendee”/> </set> few more examples: ordery-by = “last_name, first_name” order_by = “last_name, first_name asc” Use Filter to a collection Set sortedAttendees = session.filter(event.getAttendees(), “ order by this.phoneNumber”);
  • 48. Filters Filters allow you to apply filtering criteria to returned objects at the Session level. You can pass parameters to filters, and they work with classes or collections. To use filters, you first define them in the mapping files, and then enable a given filter by name when using the Session object. <hibernate-mapping> <filter-def name=“nameFilter”> <filter-param name=“nameFilterParam” type=“string”/> </fliter-def> </hibernate-mapping>
  • 49. Filters - 2 With the filter defined, we can apply it to persistent classes and colections : <class name = “Event”> <filter name=“nameFilter” condition = “:nameFilterParam=name”/> <set name=“attendees”> <filter name=“nameFilter” condition = “:nameFilterParam = last_name”/> </set> </class>
  • 50. Filters - 3 This code applies the filter to the name column in the events table, and to the last_name column in the attendees table. To apply the filters, we must explicitly enable them at the Session level ; Filter f = session.enablefilter(“nameFilter”); f.setParameter(“nameFilterParam”, “Plenary”); List results = session.createQuery(“from Event”).list(); This code enables the named filter ant then sets the filter parameter. This results will only contain instances of Event with the name Plenary. We can also enable multiple filters per session.
  • 51. Metadata alternatives Attribute-oriented metadata JSR-175 annotations support, coming soon! XDoclet Hibernate module Hibernate mapping metadata can be manipulated programmatically we can use dom4j or JDOM to generate mapping files in memory we can manipulate the Hibernate Configuration metamodel directly let's demonstrate this my adding a property to a mapped class… /** * @hibernate.class * table=&quot;CATEGORY&quot; */ public class Category { ... /** * @hibernate.property */ public String getName() { return name; } ... }
  • 52. Adding a property at runtime // Get the existing mapping for User from Configuration PersistentClass userMapping = cfg .getClassMapping(User.class); // Define a new column for the USER table Column column = new Column(); userMapping.getTable().addColumn(column); // Wrap the column in a Value SimpleValue value = new SimpleValue(); value.setTable( userMapping.getTable() ); value.addColumn(column); // Define a new property of the User class Property prop = new Property(); prop.setValue(value); prop.setName(&quot;motto&quot;); userMapping.addProperty(prop); // Build a new session factory, using the new mapping SessionFactory sf = cfg.buildSessionFactory();
  • 53. Reading metadata at runtime There is also the runtime metamodel , exposed via the SessionFactory : Category category = ...; ClassMetadata meta = sessionFactory.getClassMetadata(Category.class); String[] metaPropertyNames = meta.getPropertyNames(); Object[] propertyValues = meta.getPropertyValues(category);