SlideShare a Scribd company logo
Let ColdFusion ORM doLet ColdFusion ORM do
the work for you!the work for you!
CFSummit 2018CFSummit 2018
Presenter: Masha EdelenPresenter: Masha Edelen
Who am I?Who am I?
Full Stack Web Developer of 16+ years
HD Web Studio Owner and Visionary
Mother to a Teenage Daughter
Travel Enthusiast
Live Music Fan
Amateur Latin Dancer
www.ColdFusionORMbook.com
AgendaAgenda
Introduction to ORM
Getting Started
Relationships
HQL
Gotchas
Advanced Features
Resources
What is ORM?What is ORM?
http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSD628ADC4-A5F7-4079-99E0-FD725BE9B4BD.html
Object relational mapping (ORM) is a programming
framework that allows you to define a mapping between
application object model and the relational database.
ORM Implementaion in ColdFusionORM Implementaion in ColdFusion
Hibernate 5.3 - current stable
ColdFusion 2018 - Hibernate 5.2
ColdFusion 2016 - Hibernate 4.3
ColdFusion 11 - Hibernate 4.1
ColdFusion 10 - Hibernate 3.5
ColdFusion 9 - Hibernate 3.5
Lucee - Hibernate 3.5
Why should I use an ORM?Why should I use an ORM?
Reduces development time
Overcomes vendor specific SQL differences
Promotes effective design patterns
Reduces maintenance
Potential DownsidePotential Downside
Without proper tuning performance can suffer.
Make sure you optimize queries
and use effective caching strategy!
Getting StartedGetting Started
Step 1: Configuring ORM in your Application
Application.cfc
component {
// set the unique name of the application
this.name = "myCMS";
// set the datasource
this.datasource = "mydsn";
// turn ORM on
this.ormenabled = true;
}
Step 2: Mapping Tables to Objects
Article.cfc
/*** I model a blog article ***/
component persistent="true" table="articles" {
// identifier
property name="id" fieldtype="id" generator="native" column="articleI
// properties
property name="title" ormType="string" length="250";
property name="summary" ormType="string" length="500";
property name="description" ormType="text";
}
AccessorsAccessors
setTitle()
getTitle()
Additional ORM SettingsAdditional ORM Settings
Application.cfc
// ORM settings
this.ormsettings = {
cfclocation = ["model/beans"],
dbcreate = "update",
dialect = "MySQL",
datasource = "ORMds",
useDBForMapping = false
}
ORMReload()ORMReload()
// ORM reload on URL
if (structKeyExists(url,"reloadORM")) {
ORMReload();
}
CRUDCRUD
Source: http://docs.jboss.org/hibernate/orm/4.1/quickstart/en-US/html/pr01.html
Hibernate’s design goal is to relieve the developer from 95%
of common data persistence-related programming tasks by
eliminating the need for manual, hand-crafted data
processing using SQL and JDBC.
CreateCreate
// Create music category
myCategory = EntityNew("Category");
myCategory.setTitle("Music");
EntitySave(myCategory);
// Create sports category
myCategory = EntityNew("Category", {title:"Sports"});
EntitySave(myCategory);
// Create family category
myCategory = new model.Category(title="Family");
EntitySave(myCategory);
// Create holiday category
myCategory = EntityNew("Category");
myCategory.title = "Holiday";
EntitySave(myCategory);
ReadRead
UpdateUpdate
DeleteDelete
// Get all categories
categories = EntityLoad("Category");
WriteDump(var = categories, top = 2);
// Get category and update its title
myCategory = EntityLoadByPK("Category", 1);
myCategory.setTitle("New Title");
// Delete category
myCategory = EntityLoadByPK("Category", 1);
EntityDelete(myCategory);
More ExamplesMore Examples
// Get all categories set to display
categories = EntityLoad("Category", {dsp = true});
// Get all categories set to display and ordered chronologically
categories = EntityLoad("Category", {dsp = true}, "date desc");
More ExamplesMore Examples
// Get category by ID
myCategory = EntityLoadbyPK("Category",1);
// Get category by ID
myCategory = EntityLoad("Category",1);
myCategory = EntityLoad("Category",1,true);
Convert Object to QueryConvert Object to Query
// Convert object to query
myCategory = EntityLoadbyPK("Category",1);
myCategoryQuery = EntityToQuery(myCategory);
// Convert array of objects to query
categories = EntityLoad("Category");
categoriesQuery = EntityToQuery(categories);
Let ColdFusion ORM do the work for you!
RelationshipsRelationships
One-to-ManyOne-to-Many
Author.cfc
/*** I model an Author ***/
component persistent="true" table="authors" {
// identifier
property name="id" fieldtype="id" generator="native";
// properties
property name="firstName" ormtype="string" length="50";
property name="lastName" ormtype="string" length="50";
// one Author can have many Articles
property name="articles" fieldtype="one-to-many" cfc="Article"
fkcolumn="fk_authorid" type="array" singularname="article";
}
One-to-Many MethodsOne-to-Many Methods
addArticle()
hasArticle()
removeArticle()
setArticles()
getArticles()
One-to-Many UsageOne-to-Many Usage
// Create a new article and add to an existing author
transaction {
// load the author
author = EntityLoadByPK("author", 1);
// create an article
article = EntityNew("article");
article.setTitle("ORM Makes My Life Easy!");
// attach the article to the author
author.addArticle(article);
// save the article
EntitySave(article);
};
writeDump(author.getArticles(), top="2");
Many-to-OneMany-to-One
Article.cfc
/*** I model an article ***/
component persistent="true" table="articles" {
// identifier
property name="id" fieldtype="id" generator="native";
...
//many Article entities can have one Author entity
property name="Author" fieldtype="many-to-one"
cfc="Author" fkcolumn="fk_authorid";
}
Many-to-One MethodsMany-to-One Methods
hasAuthor()
setAuthor()
getAuthor()
Many-to-ManyMany-to-Many
Category.cfc
/*** I model a category ***/
component persistent="true" table="categories" {
//identifier
property name="id" fieldtype="id" generator="native";
...
//category can be assigned to more than one article
property name="articles" fieldtype="many-to-many"
cfc="Articles" type="array" singularname="article"
linktable="articles_categories";
}
Many-to-Many MethodsMany-to-Many Methods
addArticle()
getArticles()
hasArticle()
removeArticle()
setArticles()
OO Modeling is Key!OO Modeling is Key!
ORM Persistence Model is a set of ORM Entities
related based on business logic of the application.
Objects vs Tables
Persistence Model vs Database Schemas
Data + Behavior vs Data
The Inverse AttributeThe Inverse Attribute
Author.cfc
/*** I model an author ***/
component persistent="true" table="authors" {
...
// one author can have many articles
property name="articles" fieldtype="one-to-many"
cfc="Article" fkcolumn="fk_authorid" type="array"
singularname="article"
// added attributes
inverse="true" cascade="delete";
}
Cascading StrategiesCascading Strategies
none
delete
save-update
all
delete-orphan
all-delete-orphan
Sort OrderSort Order
Author.cfc
/*** I model an author ***/
component persistent="true" table="authors" {
...
// one author can have many articles
property name="articles" fieldtype="one-to-many"
cfc="Article" fkcolumn="fk_authorid" type="array"
singularname="article"
inverse="true" cascade="delete"
// added sorting
orderby="datepublished desc";
}
Where FilterWhere Filter
Author.cfc
/*** I model an author ***/
component persistent="true" table="authors" {
...
// getting only published articles
property name="publishedArticles" fieldtype="one-to-many"
cfc="Article" fkcolumn="fk_authorid"
orderby="datepublished desc"
// filter
where="ispublished = 1";
}
FormulasFormulas
Author.cfc
/*** I model an author ***/
component persistent="true" table="authors" {
...
// get count of active articles
property name="publishedArticleCount" setter="false"
formula="select count(*)
from Articles a
where author_pk = a.fk_authorid
and a.ispublished = 1";
}
HQLHQL
HQLHQL
Same as:
// get users
EntityLoad("User");
// get users with HQL
ORMExecuteQuery("from User");
SQL Injection PreventionSQL Injection Prevention
Same as:
Better:
Or:
// get user by ID
userid = 123;
EntityLoadByPK("User", id);
// get user by ID with HQL
ORMExecuteQuery("from User where id = #userid#", true);
// get user by ID with HQL using positional parameters
ORMExecuteQuery("from User where id = ?", [userid], true);
// get user by ID with HQL using named parameters
ORMExecuteQuery("from User where id = :id", {id=userid}, true);
HQL ExamplesHQL Examples
ORMExecuteQuery(hql, params [,unique] [,queryOptions])
// get users with usernames that start with letter J
q = ORMExecuteQuery(
"from user where username like :prefix", {prefix = "J%"}
);
// get art pieces priced over $400
q = ORMExecuteQuery(
"from art where price > :lowprice", {lowprice = 400}
);
// adding queryOptions
q = ORMExecuteQuery(
"from artist", false, {offset=5, maxresults=10, timeout=5}
);
Relationships HQLRelationships HQL
Get articles by Author ID:
The HQL way:
// load author
author = EntityLoadByPK("Author", 2);
// get this author's articles
articles = author.getArticles();
from article
where author.id = :authorID
Relationships HQLRelationships HQL
Get published articles by Author ID:
Get unique authors:
from article
where
author.id = :authorID
and
ispublished = :isPublished
select distinct a.author
from article a
where
a.ispublished = :isPublished
Hash MapsHash Maps
select new map(id as ID, title as TITLE)
from Article
order by title
From Love to Hate?From Love to Hate?
ErrorsErrors
Error during DDL export
Cannot simultaneously fetch multiple bags
Failed to lazily initialize a collection of role, no session or
session was closed
Illegal attempt to dereference collection
Incomplete Information?Incomplete Information?
LoggingLogging
{cfinstall}cfusionlog4j.properties
log4j.logger.org.hibernate.type=DEBUG
// turn on logging in development
this.ormsettings = {
...
logSQL = true
}
Hibernate Session ManagementHibernate Session Management
ORM session starts when the first CRUD method is called
and is closed when the request ends.
// manage session manually
this.ormsettings = {
...
//switch to false and use transactions
autoManageSession = false,
flushAtRequestEnd = false
}
Performance ImprovementsPerformance Improvements
Paging
Lazy Loading
Fetching Options
Batching
Caching
PagingPaging
// get 10 artists starting with #6
artists = ORMExecuteQuery(
"from artist", false, {offset=5, maxresults=10, timeout=5}
)
Lazy LoadingLazy Loading
lazy = "true" (default)
lazy = "extra"
lazy = "false"
Fetching OptionsFetching Options
fetch = "select" (default)
fetch = "join"
Batch FetchingBatch Fetching
At CFC level
At collections
// implement batching
component table="artist" batchsize="10"...
...
// get artist as usual
getArtist();
// implement batching for related entity
property name="art" fieldtype="one-to-many" cfc="art" fkcolumn="artistID" bat
...
// get all the art of a specific artist
artist.getArt();
CachingCaching
Session Level - built into ORM
Second Level - through external caching engine
Secondary Level CacheSecondary Level Cache
EHCache, JBossCache, OSCache, SwarmCache, Tangosol Coherence Cache
Application.cfc
// activate secondary level cache
this.ormSettings.secondaryCacheEnabled = true;
Secondary Level CacheSecondary Level Cache
At CFC level
At collections
// implement secondary level caching
component persistent="true" table="Artist" cacheuse="transactional" ...
// implement secondary level caching for related entities
property name="art" fieldtype="one-to-many" cfc="art" fkcolumn="artistID"
cacheuse="transactional";
Secondary Level CacheSecondary Level Cache
read-only
nonstrict-read-write
read-write
transactional
Caching HQLCaching HQL
// implement caching for HQL query
e = ORMExecuteQuery(
"from article where id = :id",
{id=1},
{cacheable=true, cachename='articles'}
);
Managing the CacheManaging the Cache
// clear cache for author
ORMEvictEntity( "author" );
ORMEvictEntity( "author", 1 );
// clear cache for articles
ORMEvictCollection( "author", "articles" );
ORMEvictCollection( "author", "articles", 1 );
// clear cache for HQL
ORMEvictQueries( "mycachename" );
ORMEvictQueries();
Advanced Use CasesAdvanced Use Cases
Query: Retrieve distinct countries of all addresses in alphabetical order.
SQL:
HQL:
Criteria API:
select distinct country from address ordered by country
select distinct country from address ordered by country
criteria.setProjection(projections.distinct(projections.property("Country")))
criteria.addOrder(order.asc("locality"));
ColdBox ORM ModuleColdBox ORM Module
https://www.forgebox.io/view/cborm
"This module provides you with several enhancements
when interacting with the ColdFusion ORM via Hibernate.
It provides you with virtual service layers, active record
patterns, criteria and detached criteria queries, entity
compositions, populations and so much more to make your
ORM life easier!
In other words, it makes using ORM not SUCK!"
There is more!There is more!
Convenience Methods
Versioning
Validation
ORM Search
Advanced Mapping
Event Handlers (Interceptors)
Online ResourcesOnline Resources
Developing Applications Adobe ColdFusion ORM
ColdFusion ORM Developer Guide
CF-ORM Google Group
Hibernate Documentation
ORM Slack Channel on CFML Slack Team
https://helpx.adobe.com/coldfusion/developing-applications/user-guide.html?topic=/coldfusion/developing-applications/morehelp/coldfusion-orm.ug.js
http://adobe.ly/LnJilm
http://groups.google.ca/group/cf-orm-dev
http://www.hibernate.org/docs
PublicationsPublications
Java Persistence with Hibernate
Adobe ColdFusion 9 Web Application Construction Kit, Volume 2:
Application Development
ColdFusion ORM
http://www.manning.com/bauer2/
http://forta.com/books/0321679199/
http://www.coldfusionormbook.com
Please submit your surveyPlease submit your survey
for a chance to win!for a chance to win!
Go to the ColdFusion Summit mobile app
Find this session: D103: Let ColdFusion ORM do the work for you!
Make sure you have registered for this session
Select the “Survey” link at the bottom of the session and complete the
survey
Each survey has a chance to win $25 Amazon Gift Certificate
Thank You!Thank You!
Masha Edelen
masha@hdwebstudio.com
@mashaedelen

More Related Content

PDF
Power of Simplicity in FW/1
ODP
Zend Framework 1.9 Setup & Using Zend_Tool
KEY
CodeIgniter 3.0
PDF
TurboGears2 Pluggable Applications
PDF
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
PDF
Introducing Assetic: Asset Management for PHP 5.3
PDF
深入淺出 MVC
PPTX
Python Code Camp for Professionals 3/4
Power of Simplicity in FW/1
Zend Framework 1.9 Setup & Using Zend_Tool
CodeIgniter 3.0
TurboGears2 Pluggable Applications
#30.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
Introducing Assetic: Asset Management for PHP 5.3
深入淺出 MVC
Python Code Camp for Professionals 3/4

What's hot (20)

PPTX
Python Code Camp for Professionals 4/4
PDF
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
PDF
Drupal 8 Services
PDF
Building a Dynamic Website Using Django
PDF
Revolution or Evolution in Page Object
PDF
You Don't Know Query (WordCamp Netherlands 2012)
PDF
Rapid Prototyping with Solr
PPTX
Python Code Camp for Professionals 1/4
PPTX
DevOps and Chef
PDF
Flask patterns
PPTX
SCULPT! YOUR! TESTS!
PDF
Head First Zend Framework - Part 1 Project & Application
PDF
Drupal 8 Services And Dependency Injection
PDF
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
PDF
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
PDF
Getting Into Drupal 8 Configuration
PDF
Advanced symfony Techniques
PDF
OSCON Google App Engine Codelab - July 2010
PDF
Doctrine 2
PDF
[WLDN] Supercharging word press development in 2018
Python Code Camp for Professionals 4/4
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
Drupal 8 Services
Building a Dynamic Website Using Django
Revolution or Evolution in Page Object
You Don't Know Query (WordCamp Netherlands 2012)
Rapid Prototyping with Solr
Python Code Camp for Professionals 1/4
DevOps and Chef
Flask patterns
SCULPT! YOUR! TESTS!
Head First Zend Framework - Part 1 Project & Application
Drupal 8 Services And Dependency Injection
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
Getting Into Drupal 8 Configuration
Advanced symfony Techniques
OSCON Google App Engine Codelab - July 2010
Doctrine 2
[WLDN] Supercharging word press development in 2018
Ad

Similar to Let ColdFusion ORM do the work for you! (20)

PDF
Javascript Frameworks for Joomla
PDF
Human Talks - StencilJS
ODP
Gears User Guide
PDF
Multilingualism makes better programmers
PDF
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
ODP
CodeIgniter PHP MVC Framework
PDF
GDI Seattle - Intro to JavaScript Class 4
PPTX
REST with Eve and Python
PDF
Doctrine For Beginners
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
PPTX
Mood analyzer-ng poland
PDF
Google App Engine in 40 minutes (the absolute essentials)
KEY
Paris js extensions
PPTX
Ingesting and Manipulating Data with JavaScript
PDF
Spca2014 hillier 3rd party_javascript_libraries
PDF
WebNet Conference 2012 - Designing complex applications using html5 and knock...
PDF
Fun Teaching MongoDB New Tricks
PDF
Tornadoweb
PDF
Questioning the status quo
Javascript Frameworks for Joomla
Human Talks - StencilJS
Gears User Guide
Multilingualism makes better programmers
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
CodeIgniter PHP MVC Framework
GDI Seattle - Intro to JavaScript Class 4
REST with Eve and Python
Doctrine For Beginners
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Mood analyzer-ng poland
Google App Engine in 40 minutes (the absolute essentials)
Paris js extensions
Ingesting and Manipulating Data with JavaScript
Spca2014 hillier 3rd party_javascript_libraries
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fun Teaching MongoDB New Tricks
Tornadoweb
Questioning the status quo
Ad

Recently uploaded (20)

PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Getting Started with Data Integration: FME Form 101
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
A comparative analysis of optical character recognition models for extracting...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
Machine Learning_overview_presentation.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Heart disease approach using modified random forest and particle swarm optimi...
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Machine learning based COVID-19 study performance prediction
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
cloud_computing_Infrastucture_as_cloud_p
Reach Out and Touch Someone: Haptics and Empathic Computing
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
gpt5_lecture_notes_comprehensive_20250812015547.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Programs and apps: productivity, graphics, security and other tools
Getting Started with Data Integration: FME Form 101
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Network Security Unit 5.pdf for BCA BBA.
A comparative analysis of optical character recognition models for extracting...
Digital-Transformation-Roadmap-for-Companies.pptx
Machine Learning_overview_presentation.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Heart disease approach using modified random forest and particle swarm optimi...
Spectral efficient network and resource selection model in 5G networks
Per capita expenditure prediction using model stacking based on satellite ima...
Machine learning based COVID-19 study performance prediction
Assigned Numbers - 2025 - Bluetooth® Document
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
MIND Revenue Release Quarter 2 2025 Press Release
cloud_computing_Infrastucture_as_cloud_p

Let ColdFusion ORM do the work for you!

  • 1. Let ColdFusion ORM doLet ColdFusion ORM do the work for you!the work for you! CFSummit 2018CFSummit 2018 Presenter: Masha EdelenPresenter: Masha Edelen
  • 2. Who am I?Who am I? Full Stack Web Developer of 16+ years HD Web Studio Owner and Visionary Mother to a Teenage Daughter Travel Enthusiast Live Music Fan Amateur Latin Dancer
  • 4. AgendaAgenda Introduction to ORM Getting Started Relationships HQL Gotchas Advanced Features Resources
  • 5. What is ORM?What is ORM? http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSD628ADC4-A5F7-4079-99E0-FD725BE9B4BD.html Object relational mapping (ORM) is a programming framework that allows you to define a mapping between application object model and the relational database.
  • 6. ORM Implementaion in ColdFusionORM Implementaion in ColdFusion Hibernate 5.3 - current stable ColdFusion 2018 - Hibernate 5.2 ColdFusion 2016 - Hibernate 4.3 ColdFusion 11 - Hibernate 4.1 ColdFusion 10 - Hibernate 3.5 ColdFusion 9 - Hibernate 3.5 Lucee - Hibernate 3.5
  • 7. Why should I use an ORM?Why should I use an ORM? Reduces development time Overcomes vendor specific SQL differences Promotes effective design patterns Reduces maintenance
  • 8. Potential DownsidePotential Downside Without proper tuning performance can suffer. Make sure you optimize queries and use effective caching strategy!
  • 9. Getting StartedGetting Started Step 1: Configuring ORM in your Application Application.cfc component { // set the unique name of the application this.name = "myCMS"; // set the datasource this.datasource = "mydsn"; // turn ORM on this.ormenabled = true; }
  • 10. Step 2: Mapping Tables to Objects Article.cfc /*** I model a blog article ***/ component persistent="true" table="articles" { // identifier property name="id" fieldtype="id" generator="native" column="articleI // properties property name="title" ormType="string" length="250"; property name="summary" ormType="string" length="500"; property name="description" ormType="text"; }
  • 12. Additional ORM SettingsAdditional ORM Settings Application.cfc // ORM settings this.ormsettings = { cfclocation = ["model/beans"], dbcreate = "update", dialect = "MySQL", datasource = "ORMds", useDBForMapping = false }
  • 13. ORMReload()ORMReload() // ORM reload on URL if (structKeyExists(url,"reloadORM")) { ORMReload(); }
  • 14. CRUDCRUD Source: http://docs.jboss.org/hibernate/orm/4.1/quickstart/en-US/html/pr01.html Hibernate’s design goal is to relieve the developer from 95% of common data persistence-related programming tasks by eliminating the need for manual, hand-crafted data processing using SQL and JDBC.
  • 15. CreateCreate // Create music category myCategory = EntityNew("Category"); myCategory.setTitle("Music"); EntitySave(myCategory); // Create sports category myCategory = EntityNew("Category", {title:"Sports"}); EntitySave(myCategory); // Create family category myCategory = new model.Category(title="Family"); EntitySave(myCategory); // Create holiday category myCategory = EntityNew("Category"); myCategory.title = "Holiday"; EntitySave(myCategory);
  • 16. ReadRead UpdateUpdate DeleteDelete // Get all categories categories = EntityLoad("Category"); WriteDump(var = categories, top = 2); // Get category and update its title myCategory = EntityLoadByPK("Category", 1); myCategory.setTitle("New Title"); // Delete category myCategory = EntityLoadByPK("Category", 1); EntityDelete(myCategory);
  • 17. More ExamplesMore Examples // Get all categories set to display categories = EntityLoad("Category", {dsp = true}); // Get all categories set to display and ordered chronologically categories = EntityLoad("Category", {dsp = true}, "date desc");
  • 18. More ExamplesMore Examples // Get category by ID myCategory = EntityLoadbyPK("Category",1); // Get category by ID myCategory = EntityLoad("Category",1); myCategory = EntityLoad("Category",1,true);
  • 19. Convert Object to QueryConvert Object to Query // Convert object to query myCategory = EntityLoadbyPK("Category",1); myCategoryQuery = EntityToQuery(myCategory); // Convert array of objects to query categories = EntityLoad("Category"); categoriesQuery = EntityToQuery(categories);
  • 22. One-to-ManyOne-to-Many Author.cfc /*** I model an Author ***/ component persistent="true" table="authors" { // identifier property name="id" fieldtype="id" generator="native"; // properties property name="firstName" ormtype="string" length="50"; property name="lastName" ormtype="string" length="50"; // one Author can have many Articles property name="articles" fieldtype="one-to-many" cfc="Article" fkcolumn="fk_authorid" type="array" singularname="article"; }
  • 24. One-to-Many UsageOne-to-Many Usage // Create a new article and add to an existing author transaction { // load the author author = EntityLoadByPK("author", 1); // create an article article = EntityNew("article"); article.setTitle("ORM Makes My Life Easy!"); // attach the article to the author author.addArticle(article); // save the article EntitySave(article); }; writeDump(author.getArticles(), top="2");
  • 25. Many-to-OneMany-to-One Article.cfc /*** I model an article ***/ component persistent="true" table="articles" { // identifier property name="id" fieldtype="id" generator="native"; ... //many Article entities can have one Author entity property name="Author" fieldtype="many-to-one" cfc="Author" fkcolumn="fk_authorid"; }
  • 27. Many-to-ManyMany-to-Many Category.cfc /*** I model a category ***/ component persistent="true" table="categories" { //identifier property name="id" fieldtype="id" generator="native"; ... //category can be assigned to more than one article property name="articles" fieldtype="many-to-many" cfc="Articles" type="array" singularname="article" linktable="articles_categories"; }
  • 29. OO Modeling is Key!OO Modeling is Key! ORM Persistence Model is a set of ORM Entities related based on business logic of the application. Objects vs Tables Persistence Model vs Database Schemas Data + Behavior vs Data
  • 30. The Inverse AttributeThe Inverse Attribute Author.cfc /*** I model an author ***/ component persistent="true" table="authors" { ... // one author can have many articles property name="articles" fieldtype="one-to-many" cfc="Article" fkcolumn="fk_authorid" type="array" singularname="article" // added attributes inverse="true" cascade="delete"; }
  • 32. Sort OrderSort Order Author.cfc /*** I model an author ***/ component persistent="true" table="authors" { ... // one author can have many articles property name="articles" fieldtype="one-to-many" cfc="Article" fkcolumn="fk_authorid" type="array" singularname="article" inverse="true" cascade="delete" // added sorting orderby="datepublished desc"; }
  • 33. Where FilterWhere Filter Author.cfc /*** I model an author ***/ component persistent="true" table="authors" { ... // getting only published articles property name="publishedArticles" fieldtype="one-to-many" cfc="Article" fkcolumn="fk_authorid" orderby="datepublished desc" // filter where="ispublished = 1"; }
  • 34. FormulasFormulas Author.cfc /*** I model an author ***/ component persistent="true" table="authors" { ... // get count of active articles property name="publishedArticleCount" setter="false" formula="select count(*) from Articles a where author_pk = a.fk_authorid and a.ispublished = 1"; }
  • 36. HQLHQL Same as: // get users EntityLoad("User"); // get users with HQL ORMExecuteQuery("from User");
  • 37. SQL Injection PreventionSQL Injection Prevention Same as: Better: Or: // get user by ID userid = 123; EntityLoadByPK("User", id); // get user by ID with HQL ORMExecuteQuery("from User where id = #userid#", true); // get user by ID with HQL using positional parameters ORMExecuteQuery("from User where id = ?", [userid], true); // get user by ID with HQL using named parameters ORMExecuteQuery("from User where id = :id", {id=userid}, true);
  • 38. HQL ExamplesHQL Examples ORMExecuteQuery(hql, params [,unique] [,queryOptions]) // get users with usernames that start with letter J q = ORMExecuteQuery( "from user where username like :prefix", {prefix = "J%"} ); // get art pieces priced over $400 q = ORMExecuteQuery( "from art where price > :lowprice", {lowprice = 400} ); // adding queryOptions q = ORMExecuteQuery( "from artist", false, {offset=5, maxresults=10, timeout=5} );
  • 39. Relationships HQLRelationships HQL Get articles by Author ID: The HQL way: // load author author = EntityLoadByPK("Author", 2); // get this author's articles articles = author.getArticles(); from article where author.id = :authorID
  • 40. Relationships HQLRelationships HQL Get published articles by Author ID: Get unique authors: from article where author.id = :authorID and ispublished = :isPublished select distinct a.author from article a where a.ispublished = :isPublished
  • 41. Hash MapsHash Maps select new map(id as ID, title as TITLE) from Article order by title
  • 42. From Love to Hate?From Love to Hate?
  • 43. ErrorsErrors Error during DDL export Cannot simultaneously fetch multiple bags Failed to lazily initialize a collection of role, no session or session was closed Illegal attempt to dereference collection
  • 45. LoggingLogging {cfinstall}cfusionlog4j.properties log4j.logger.org.hibernate.type=DEBUG // turn on logging in development this.ormsettings = { ... logSQL = true }
  • 46. Hibernate Session ManagementHibernate Session Management ORM session starts when the first CRUD method is called and is closed when the request ends. // manage session manually this.ormsettings = { ... //switch to false and use transactions autoManageSession = false, flushAtRequestEnd = false }
  • 47. Performance ImprovementsPerformance Improvements Paging Lazy Loading Fetching Options Batching Caching
  • 48. PagingPaging // get 10 artists starting with #6 artists = ORMExecuteQuery( "from artist", false, {offset=5, maxresults=10, timeout=5} )
  • 49. Lazy LoadingLazy Loading lazy = "true" (default) lazy = "extra" lazy = "false"
  • 50. Fetching OptionsFetching Options fetch = "select" (default) fetch = "join"
  • 51. Batch FetchingBatch Fetching At CFC level At collections // implement batching component table="artist" batchsize="10"... ... // get artist as usual getArtist(); // implement batching for related entity property name="art" fieldtype="one-to-many" cfc="art" fkcolumn="artistID" bat ... // get all the art of a specific artist artist.getArt();
  • 52. CachingCaching Session Level - built into ORM Second Level - through external caching engine
  • 53. Secondary Level CacheSecondary Level Cache EHCache, JBossCache, OSCache, SwarmCache, Tangosol Coherence Cache Application.cfc // activate secondary level cache this.ormSettings.secondaryCacheEnabled = true;
  • 54. Secondary Level CacheSecondary Level Cache At CFC level At collections // implement secondary level caching component persistent="true" table="Artist" cacheuse="transactional" ... // implement secondary level caching for related entities property name="art" fieldtype="one-to-many" cfc="art" fkcolumn="artistID" cacheuse="transactional";
  • 55. Secondary Level CacheSecondary Level Cache read-only nonstrict-read-write read-write transactional
  • 56. Caching HQLCaching HQL // implement caching for HQL query e = ORMExecuteQuery( "from article where id = :id", {id=1}, {cacheable=true, cachename='articles'} );
  • 57. Managing the CacheManaging the Cache // clear cache for author ORMEvictEntity( "author" ); ORMEvictEntity( "author", 1 ); // clear cache for articles ORMEvictCollection( "author", "articles" ); ORMEvictCollection( "author", "articles", 1 ); // clear cache for HQL ORMEvictQueries( "mycachename" ); ORMEvictQueries();
  • 58. Advanced Use CasesAdvanced Use Cases Query: Retrieve distinct countries of all addresses in alphabetical order. SQL: HQL: Criteria API: select distinct country from address ordered by country select distinct country from address ordered by country criteria.setProjection(projections.distinct(projections.property("Country"))) criteria.addOrder(order.asc("locality"));
  • 59. ColdBox ORM ModuleColdBox ORM Module https://www.forgebox.io/view/cborm "This module provides you with several enhancements when interacting with the ColdFusion ORM via Hibernate. It provides you with virtual service layers, active record patterns, criteria and detached criteria queries, entity compositions, populations and so much more to make your ORM life easier! In other words, it makes using ORM not SUCK!"
  • 60. There is more!There is more! Convenience Methods Versioning Validation ORM Search Advanced Mapping Event Handlers (Interceptors)
  • 61. Online ResourcesOnline Resources Developing Applications Adobe ColdFusion ORM ColdFusion ORM Developer Guide CF-ORM Google Group Hibernate Documentation ORM Slack Channel on CFML Slack Team https://helpx.adobe.com/coldfusion/developing-applications/user-guide.html?topic=/coldfusion/developing-applications/morehelp/coldfusion-orm.ug.js http://adobe.ly/LnJilm http://groups.google.ca/group/cf-orm-dev http://www.hibernate.org/docs
  • 62. PublicationsPublications Java Persistence with Hibernate Adobe ColdFusion 9 Web Application Construction Kit, Volume 2: Application Development ColdFusion ORM http://www.manning.com/bauer2/ http://forta.com/books/0321679199/ http://www.coldfusionormbook.com
  • 63. Please submit your surveyPlease submit your survey for a chance to win!for a chance to win! Go to the ColdFusion Summit mobile app Find this session: D103: Let ColdFusion ORM do the work for you! Make sure you have registered for this session Select the “Survey” link at the bottom of the session and complete the survey Each survey has a chance to win $25 Amazon Gift Certificate