Slaying the ORM Dragons
with CBORM
WHO AM I?
• Luis Majano - Computer Engineer
• Imported from El Salvador----------->
• Architecture + Software Design
• CEO of Ortus Solutions
• Adobe Community Professional
• Creator of all things Box: 

ColdBox, ContentBox,
CommandBox,WireBox….
AGENDA
• ORM FirstThoughts
• Is ORM a Silver Bullet?
• Visit from a Special Guest
• Specialized ORM Services
ORMThoughts?
CF ORM was
easier to use?
OO way to
query
ORM was fast
80% of API
Querying
Extensible
way to finish
the remaining
20%
When is
HappyBox?
Auto build
relationships
CONCLUSIONS
• Can’t or doesn’t exist
• Sounds like bull…..
• What’s this latino up to?
• Is he trying to get my money
PROVE IT!
ORM is NOT a silver bullet
• Just another tool
• Times you need the power of the database: reports, legacy, sp, etc.
• Mix and match
• What if you wanted array of structs, or lists or queries or arrays of data?
• There is a learning curve, but it is worth the investment
Applied Benefits
• Increase in productivity of about 40%
• Rich Object Models
• Deliver DB patching updates
• Increased Flexibility
• Great for abstracting vendor specific
intricacies
• OO Queries
• Avg JDBC <10ms of about 350K
Transactions
How do we start?
coldfusionormbook.com amazon
Guru ORMLui
10 keys to ORM Success!
#1: OO Modeling is Key
• ORM relationship modeling is key
• OO is required
• UML is your best friend
• STOPTHINKING ABOUT DATA
• YOU ARE NOT MODELING A DATABASE
#1: OO Modeling is Key
#1: OO Modeling is Key
Query Object
Data Data + Behavior
#2: Bad Engine Defaults
Do not use engine defaults:
Control Data Flushing +Transaction Borders:


ormsettings.flushAtRequestEnd=false
ormsettings.autoManageSession=false
Control Database Dialects (If Possible)
ormsettings.dialect=“MySQLwithInnoDB”
#2: Bad Engine Defaults
• this.ormsettings.cfclocation
• Use it to a specified directory, else pay the price of discovery
• this.ormsettings.logSQL=true
• Great for debugging, false for production, else pay the price
• Having Issues?
• Hibernate MXML: this.ormsettings.saveMapping=true
• DataBoss - ortussolutions.com/products/databoss
#3: Understand Hibernate Session
• Not the same as session scope
• A transitionary space + Caching Layer
• entityLoad()
• entityNew() ?
• You need to control when to send to DB
• transaction{}, ormflush()
• You can remove entities from it and clear it
• ORMClearSession()
• ORMEvictEntity(), ORMEvictCollection()
• ORMCloseSession()
#3: Understand Hibernate Session
Hibernate Session 

(Conversation - Request)
DB
Eu
Ex EzEy
Cache
ehCache/
Couchbase
Batched SQL
EntityNew()
EntityLoad()
Data (!CFCs)
Hibernate Session
Factory (application)
CRUD
When?
ORMClearSession()
#3: Understand Hibernate Session
DB	Sync
Insertions	in	order
updates
Collection	deletions
collection	deletion,	updates,	inserts
collection	insertions
deletions	in	order
#4:Transaction Demarcation
• Transactions demarcate SQL boundaries
• Important Imperative for ORM + SQL
• No communication to DB should occur without one
• Reactive programming, expect the worst
• cftransaction or Hibernate transactions
#4:Transaction Demarcation
• Transaction Theory:
• Any existing ORM session is flushed and reused
• Data can be committed or rollback
• ORMFlush() is ignored in transactions
• If commit, then flushed to database
• If rollback, session is cleared
#5 Lazyness
• Immediate Fetching (Default)
• select with left outer join

poor, poor, poor, poor performance
• Use lazy For ALL Relationships or pay the price
• Three types of laziness:
• lazy=“true”
• all relationships
• Loads all the relationship data when called upon (Batch sizes if used)
• lazy=“extra”
• one-to-many, many-to-many
• Loads proxies with primary keys (Event better - Batch sizes if used)
• lazy=“proxy”
• one-to-one, many-to-one
• Loads proxy with primary key
• Eager Fetching
• Mostly used in one-to-one and many-to-one, but applies to all
• Default uses 2 SQL queries, reduce to 1 Query
• property name=“role” fieldtype=“many-to-one” fetch=“join”;
• Batch Fetching
• Limits the way relationships are loaded, else Hibernate tries to load all records
• Used on many-to-many and one-to-many collection properties:
• property name=“comments” fieldtype=“one-to-many” batchsize=“10” lazy=“extra”;
• Used at entity level as well:
• component name=“Comment” batchsize=10{}
#5 Lazyness
Oracle Tip
• JDBC Fetch Sizes are defaulted to 10
• Slow for many records or batch operations
• Increase the JDBC Fetch size
• Custom Hibernate setting
• hibernate.jdbc.fetch_size=100
#5 Lazyness
#6:Avoid bi-directional
• They can be more of a headache
• Cascading Deletes
• Choose the master relationship
• inverse=true
• Else double queries
• Does it make sense?
• Supporting methods for bi-directional linkage
• Supporting methods for un-linkages
#6:Avoid bi-directional
#6:Avoid bi-directional
#7: Do not store entities in scopes
• Don’t do it!
• No linkage to Hibernate Session
• Relationships will fail if not lazy
• entityMerge()
• Store ID’s instead
#8: Use DB Indexes
• #1 Performance Problem
• Identify relationships
• Identify HQL, SQL
• property name=“isActive” index=“idxActive”
#9: Cache = BOOST!
• Don’t go cache crazy
• Develop a strategy
• Does not store CFC, stores individual property values
• Use distributed caches: ehcache, couchbase
• You can cache:
• Entity property data : Only caches properties data values
• Entity association data : Only caches primary keys
• Query data : HQL, ORMExecuteQuery()
• Evictions:
• ORMEvictEntity(), ORMEvictCollection()
#10: HQL Maps
select new map( 

max( bodyWeight ) as max, 

min( bodyWeight ) as min, 

count( * ) as n
)
from Cat cat
• Return array of structs
• Why a full ORM Object graph?
• Boost your APIs, stop converting queries/array of
objects to JSON
ORM Module
install cborm
ORM Module
Base ORM Service
Virtual ORM Service
Active Entity
Entity Populators
Validation
Event Handlers

DI/AOP
Base ORM Service
• Service layer for any entity
• OO Querying, caching, transactions
• Dynamic finders, getters, counters
• Object metadata & session management
• Exposes more features from Hibernate
• 90% Foundation
• Extends Base ORM Services
• Roots itself to a single entity = LessTyping
• You can build the 10%
Virtual/Concrete ORM
Services
• Active Record Pattern
• Sweet validation integration
• DI/AOP Available
Active Entity
• Populate Entities: xml, json, queries, structs
• Compose relationships from simple values
• Null support
• Exclude/include fields
• Server side validation
• Dependency Injection Listeners
• Custom Event Driven Programming
Entity Populators
Validation
Event Handlers
ORM Utilities
ORM Services in Action
box install cartracker-demo
Base ORM Service
• count(), countWhere()
• delete(), deleteAll(), deleteByID(), deleteByQuery(), delete Where()
• evict(), evictEntity(), evictQueries()
• executeQuery(), list()
• exists()
• findAll(), findAllWhere(), findByExample(), findIt(), findWhere()
• get(), getAll(),
• getKey(), getPropertyNames(), getSessionStatistics(), getTableName()
• clear(), merge(), new(), refresh()
• populate(), populateFromJSON(), populateFromXML(), populateFromQuery()
• save(), saveAll()
Base ORM Service
Dynamic Finders/Counters
• Expressive Programming
• Three types of dynamic Finders/Counters
• findBy : find ONE entity
• findAllBy : find ALL entities
• countBy: Give you a count
Base ORM Service
Dynamic Finders/Counters
• Conditionals
• LessThanEquals, LessThan
• GreaterThanEquals, GreaterThan
• Like
• Equal, NotEqual
• isNull, isNotNull
• Between, NotBetween
• inList, notInList
• Operators
• And
• Or
• Query Options
• ignoreCase, timeout, max, offset
• cacheable, cachename
Criteria Builder
Awesome OO Queries
Criteria Builder
• Limitations of CF ORM:
• entityLoad() has limited features
• Some operations we always need an entity = slow
• What if I want arrays, or arrays of structs
• Complex relationships are hard to query
• SQL/HQL string build is so 90’s == NOT FUN!
Criteria Builder
• Programmatic DSL Builder
• Rich set of criterias
• Projections and Result transformations
• Subqueries
• Caching
• SQL Inspections & Debugging
• Array of structures is twice as fast as
queries
Criteria Builder
Criteria Builder
• Request new criteria
• newCriteria()
• Add simple restriction(s)
• Find all cars sold between April and July
• Use between()
• Get results
• Use list( max, offset, timeout, sortOrder, ignoreCase, asQuery )
• Get counts
• Use count()
Criteria Builder
Restrictions
• between()
• eq()
• gt()
• ge()
• gtProperty()
• isEmpty()
• isNull()
• ne()
• ilike()
• and()
• or()
• not()
• conjunction()
• disjunction()
• isTrue()
• isFalse()
• sqlRestriction()
• ...much more!
Criteria Builder
Retrievals
• Retrieval
• firstResult()
• get()
• list()
• count()
• Options
• fetchSize()
• readOnly()
• maxResults()
• cache(), cacheRegion()
• timeout()
• order()
Criteria Builder
Aliases -> Joins
• Allows you to do queries within
relationships
• Creates SQL Joins
• Aliases can be nested, so if your entity
knows about it, you can query it!
Criteria Builder
Projections
• Projects change nature of results
• Arrays of data, or arrays of structs (Mighty Fast)
• Once its added its there forever
• avg
• count
• countDistinct
• distinct
• groupProperty
• max
• min
• property
• sum
• rowCount
• id
• sqlProjection
• sqlGroupProjection
• detachedSQLProjection
Criteria Builder
Debugging + Logging
• Criteria Builder SQL Inspector
• startSQLLog( returnExecutableSQL, formatSQL )
• stopSQLLog()
• getSQLLog()
• getSQL( returnExecutableSQL, formatSQL )
Thanks!
Q & A

ITB2017 - Slaying the ORM dragons with cborm

  • 2.
    Slaying the ORMDragons with CBORM
  • 3.
    WHO AM I? •Luis Majano - Computer Engineer • Imported from El Salvador-----------> • Architecture + Software Design • CEO of Ortus Solutions • Adobe Community Professional • Creator of all things Box: 
 ColdBox, ContentBox, CommandBox,WireBox….
  • 4.
    AGENDA • ORM FirstThoughts •Is ORM a Silver Bullet? • Visit from a Special Guest • Specialized ORM Services
  • 5.
    ORMThoughts? CF ORM was easierto use? OO way to query ORM was fast 80% of API Querying Extensible way to finish the remaining 20% When is HappyBox? Auto build relationships
  • 6.
    CONCLUSIONS • Can’t ordoesn’t exist • Sounds like bull….. • What’s this latino up to? • Is he trying to get my money PROVE IT!
  • 7.
    ORM is NOTa silver bullet • Just another tool • Times you need the power of the database: reports, legacy, sp, etc. • Mix and match • What if you wanted array of structs, or lists or queries or arrays of data? • There is a learning curve, but it is worth the investment
  • 8.
    Applied Benefits • Increasein productivity of about 40% • Rich Object Models • Deliver DB patching updates • Increased Flexibility • Great for abstracting vendor specific intricacies • OO Queries • Avg JDBC <10ms of about 350K Transactions
  • 9.
    How do westart? coldfusionormbook.com amazon
  • 10.
    Guru ORMLui 10 keysto ORM Success!
  • 11.
    #1: OO Modelingis Key • ORM relationship modeling is key • OO is required • UML is your best friend • STOPTHINKING ABOUT DATA • YOU ARE NOT MODELING A DATABASE
  • 12.
  • 13.
    #1: OO Modelingis Key Query Object Data Data + Behavior
  • 14.
    #2: Bad EngineDefaults Do not use engine defaults: Control Data Flushing +Transaction Borders: 
 ormsettings.flushAtRequestEnd=false ormsettings.autoManageSession=false Control Database Dialects (If Possible) ormsettings.dialect=“MySQLwithInnoDB”
  • 15.
    #2: Bad EngineDefaults • this.ormsettings.cfclocation • Use it to a specified directory, else pay the price of discovery • this.ormsettings.logSQL=true • Great for debugging, false for production, else pay the price • Having Issues? • Hibernate MXML: this.ormsettings.saveMapping=true • DataBoss - ortussolutions.com/products/databoss
  • 16.
    #3: Understand HibernateSession • Not the same as session scope • A transitionary space + Caching Layer • entityLoad() • entityNew() ? • You need to control when to send to DB • transaction{}, ormflush() • You can remove entities from it and clear it • ORMClearSession() • ORMEvictEntity(), ORMEvictCollection() • ORMCloseSession()
  • 17.
    #3: Understand HibernateSession Hibernate Session 
 (Conversation - Request) DB Eu Ex EzEy Cache ehCache/ Couchbase Batched SQL EntityNew() EntityLoad() Data (!CFCs) Hibernate Session Factory (application) CRUD When? ORMClearSession()
  • 18.
    #3: Understand HibernateSession DB Sync Insertions in order updates Collection deletions collection deletion, updates, inserts collection insertions deletions in order
  • 19.
    #4:Transaction Demarcation • Transactionsdemarcate SQL boundaries • Important Imperative for ORM + SQL • No communication to DB should occur without one • Reactive programming, expect the worst • cftransaction or Hibernate transactions
  • 20.
    #4:Transaction Demarcation • TransactionTheory: • Any existing ORM session is flushed and reused • Data can be committed or rollback • ORMFlush() is ignored in transactions • If commit, then flushed to database • If rollback, session is cleared
  • 21.
    #5 Lazyness • ImmediateFetching (Default) • select with left outer join
 poor, poor, poor, poor performance • Use lazy For ALL Relationships or pay the price • Three types of laziness: • lazy=“true” • all relationships • Loads all the relationship data when called upon (Batch sizes if used) • lazy=“extra” • one-to-many, many-to-many • Loads proxies with primary keys (Event better - Batch sizes if used) • lazy=“proxy” • one-to-one, many-to-one • Loads proxy with primary key
  • 22.
    • Eager Fetching •Mostly used in one-to-one and many-to-one, but applies to all • Default uses 2 SQL queries, reduce to 1 Query • property name=“role” fieldtype=“many-to-one” fetch=“join”; • Batch Fetching • Limits the way relationships are loaded, else Hibernate tries to load all records • Used on many-to-many and one-to-many collection properties: • property name=“comments” fieldtype=“one-to-many” batchsize=“10” lazy=“extra”; • Used at entity level as well: • component name=“Comment” batchsize=10{} #5 Lazyness
  • 23.
    Oracle Tip • JDBCFetch Sizes are defaulted to 10 • Slow for many records or batch operations • Increase the JDBC Fetch size • Custom Hibernate setting • hibernate.jdbc.fetch_size=100 #5 Lazyness
  • 24.
    #6:Avoid bi-directional • Theycan be more of a headache • Cascading Deletes • Choose the master relationship • inverse=true • Else double queries • Does it make sense? • Supporting methods for bi-directional linkage • Supporting methods for un-linkages
  • 25.
  • 26.
  • 27.
    #7: Do notstore entities in scopes • Don’t do it! • No linkage to Hibernate Session • Relationships will fail if not lazy • entityMerge() • Store ID’s instead
  • 28.
    #8: Use DBIndexes • #1 Performance Problem • Identify relationships • Identify HQL, SQL • property name=“isActive” index=“idxActive”
  • 29.
    #9: Cache =BOOST! • Don’t go cache crazy • Develop a strategy • Does not store CFC, stores individual property values • Use distributed caches: ehcache, couchbase • You can cache: • Entity property data : Only caches properties data values • Entity association data : Only caches primary keys • Query data : HQL, ORMExecuteQuery() • Evictions: • ORMEvictEntity(), ORMEvictCollection()
  • 30.
    #10: HQL Maps selectnew map( 
 max( bodyWeight ) as max, 
 min( bodyWeight ) as min, 
 count( * ) as n ) from Cat cat • Return array of structs • Why a full ORM Object graph? • Boost your APIs, stop converting queries/array of objects to JSON
  • 31.
  • 32.
    ORM Module Base ORMService Virtual ORM Service Active Entity Entity Populators Validation Event Handlers
 DI/AOP
  • 33.
    Base ORM Service •Service layer for any entity • OO Querying, caching, transactions • Dynamic finders, getters, counters • Object metadata & session management • Exposes more features from Hibernate • 90% Foundation
  • 34.
    • Extends BaseORM Services • Roots itself to a single entity = LessTyping • You can build the 10% Virtual/Concrete ORM Services
  • 35.
    • Active RecordPattern • Sweet validation integration • DI/AOP Available Active Entity
  • 36.
    • Populate Entities:xml, json, queries, structs • Compose relationships from simple values • Null support • Exclude/include fields • Server side validation • Dependency Injection Listeners • Custom Event Driven Programming Entity Populators Validation Event Handlers ORM Utilities
  • 37.
    ORM Services inAction box install cartracker-demo
  • 38.
    Base ORM Service •count(), countWhere() • delete(), deleteAll(), deleteByID(), deleteByQuery(), delete Where() • evict(), evictEntity(), evictQueries() • executeQuery(), list() • exists() • findAll(), findAllWhere(), findByExample(), findIt(), findWhere() • get(), getAll(), • getKey(), getPropertyNames(), getSessionStatistics(), getTableName() • clear(), merge(), new(), refresh() • populate(), populateFromJSON(), populateFromXML(), populateFromQuery() • save(), saveAll()
  • 39.
    Base ORM Service DynamicFinders/Counters • Expressive Programming • Three types of dynamic Finders/Counters • findBy : find ONE entity • findAllBy : find ALL entities • countBy: Give you a count
  • 40.
    Base ORM Service DynamicFinders/Counters • Conditionals • LessThanEquals, LessThan • GreaterThanEquals, GreaterThan • Like • Equal, NotEqual • isNull, isNotNull • Between, NotBetween • inList, notInList • Operators • And • Or • Query Options • ignoreCase, timeout, max, offset • cacheable, cachename
  • 41.
  • 42.
    Criteria Builder • Limitationsof CF ORM: • entityLoad() has limited features • Some operations we always need an entity = slow • What if I want arrays, or arrays of structs • Complex relationships are hard to query • SQL/HQL string build is so 90’s == NOT FUN!
  • 43.
    Criteria Builder • ProgrammaticDSL Builder • Rich set of criterias • Projections and Result transformations • Subqueries • Caching • SQL Inspections & Debugging • Array of structures is twice as fast as queries
  • 44.
  • 45.
    Criteria Builder • Requestnew criteria • newCriteria() • Add simple restriction(s) • Find all cars sold between April and July • Use between() • Get results • Use list( max, offset, timeout, sortOrder, ignoreCase, asQuery ) • Get counts • Use count()
  • 46.
    Criteria Builder Restrictions • between() •eq() • gt() • ge() • gtProperty() • isEmpty() • isNull() • ne() • ilike() • and() • or() • not() • conjunction() • disjunction() • isTrue() • isFalse() • sqlRestriction() • ...much more!
  • 47.
    Criteria Builder Retrievals • Retrieval •firstResult() • get() • list() • count() • Options • fetchSize() • readOnly() • maxResults() • cache(), cacheRegion() • timeout() • order()
  • 48.
    Criteria Builder Aliases ->Joins • Allows you to do queries within relationships • Creates SQL Joins • Aliases can be nested, so if your entity knows about it, you can query it!
  • 49.
    Criteria Builder Projections • Projectschange nature of results • Arrays of data, or arrays of structs (Mighty Fast) • Once its added its there forever • avg • count • countDistinct • distinct • groupProperty • max • min • property • sum • rowCount • id • sqlProjection • sqlGroupProjection • detachedSQLProjection
  • 50.
    Criteria Builder Debugging +Logging • Criteria Builder SQL Inspector • startSQLLog( returnExecutableSQL, formatSQL ) • stopSQLLog() • getSQLLog() • getSQL( returnExecutableSQL, formatSQL )
  • 51.