BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
ortussolutions
100 views
34 slides
Apr 24, 2024
Slide 1 of 75
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
About This Presentation
Feeling lost in the trenches of complex SQL queries and manual database interaction? Join us for a beginner-friendly mission to conquer your data with ColdFusion ORM powered by Hibernate! Whether you're a fresh recruit in the coding field or a seasoned veteran navigating legacy ColdFusion applic...
Feeling lost in the trenches of complex SQL queries and manual database interaction? Join us for a beginner-friendly mission to conquer your data with ColdFusion ORM powered by Hibernate! Whether you're a fresh recruit in the coding field or a seasoned veteran navigating legacy ColdFusion applications, this session equips you with the tools and strategies to level up your development game. We will cover ORM session management, ORM settings, caching strategies, virtual service layers, dynamic finders, dynamic counters, and an enhanced Hibernate Criteria builder for ColdFusion to create easy and programmatic HQL queries. We will even see how to build automatic CRUD APIs using only your ORM definitions. Ready to win?
Size: 23.91 MB
Language: en
Added: Apr 24, 2024
Slides: 34 pages
Slide Content
By Luis Majano
ORM
Battlefield
@lmajano
@ortussolutions
•Salvadorean Born!
•Imported to the USA
•On-loan to Spain!
•Computer Engineering
•CEO of Ortus Solutions
MAJANO
LUIS
➡How to use the ColdFusion ORM
➡When to use the ColdFusion ORM
➡Tips & Trips to master Hibernate ORM
➡Pitfalls to avoid
➡Architectural overviews of ORM
➡Extend ORM
Agenda
➡Object Relational Mapper
➡Maps:
-Objects to tables
-Properties to columns
-Relationships to foreign keys and tables
➡An easier way to persist data vs. boring CRUD SQL
➡Focus on objects instead of data
➡ColdFusion ORM (Abstraction to Hibernate/JPA)
➡Almost Everything in Hibernate works in CF
ORM
What is
?
➡Write less boilerplate boring SQL
➡Increase in productivity
➡Rich Object Models
➡Increased Flexibility
➡Database vendor abstraction
➡OO instead of query-based
➡but…..
BENEFITS
Is it a Silver Bullet ?
➡Just another tool
➡Times you need the power of the database: reports, legacy, sp, etc.
➡Mix and Match
➡There is a learning curve, but it is worth the investment
➡What if you wanted an array of structs, list queries, or data arrays?
Use it Wisely!
###--------------- Hibernate Log Settings ------
### Set Hibernate log
log4j.logger.org.hibernate=INFO, HIBERNATECONSOLE
### log just the SQL
log4j.logger.org.hibernate.SQL=DEBUG, HIBERNATECONSOLE
log4j.additivity.org.hibernate.SQL=true
### Also log the parameter binding to the prepared statements.
log4j.logger.org.hibernate.type=DEBUG
### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=DEBUG, HIBERNATECONSOLE
### log cache activity ###
log4j.logger.org.hibernate.cache=DEBUG, HIBERNATECONSOLE
#---------------------------------------------
WEB-INF/cfusion/lib/log4j.properties
Log4J
Logging
No Object Modeling
#1 Failure
➡ORM relationship modeling is key
➡OO is required
➡UML is your best friend
➡STOP THINKING ABOUT DATA
➡YOU ARE NOT MODELING A DATABASE
OO Modeling is Key
OO Modeling is Key
Query Object
Data Data + Behavior
OO Modeling is Key
#2 RELATIONSHIPS
one-to-one
Student Metadata
one-to-many
Student Address
many-to-one
User Role
many-to-many
User Permissions
fieldtype=“”
RELATIONSHIPS
➡Unidirectional or Bidirectional
➡Collections can be as arrays or structs
➡Filtered Collections (Missed by devs)
➡Performance Failures
➡Control when they are loaded (lazyness)
➡Control how many related entities are loaded
➡Executing code on loading
➡The hardest part of ORM
RELATIONSHIPS
➡one-to-many, many-to-many
➡add<relationship_property_name>(<associated_object>)
➡boolean remove<relationship_property_name>(<associated_object>)
➡boolean has<relationship_property_name>(<associated_object>)
➡many-to-one, one-to-one
➡boolean has<relationship_property_name>()
•addArts( Art art )
•removeArts( Art art )
•hasArts()
•hasArts( Art art )
property name=“arts"
fieldtype="one-to-many"
cfc="Art"
fkcolumn=“ArtistID";
GENERATED
METHODS
YOU HAVE TO BE
LAZY
➡Immediate Fetching (Default)
➡select with left outer join
poor, poor, poor, poor performance
➡Use lazy For ALL Relationships or pay the price YOU HAVE TO BE
LAZY
➡Three types of laziness values:
lazy=“true”
all relationships
Loads the relationship data when the getter is called (Batches, if used)
lazy=“extra”
one-to-many, many-to-many
Loads proxy light objects with primary keys
(Event better - Batches, if used)
lazy=“proxy”
one-to-one, many-to-one
Loads proxy with primary key (Same as above) YOU HAVE TO BE
LAZY
➡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{} YOU HAVE TO BE
LAZY
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 YOU HAVE TO BE
LAZY
➡They can be more of a headache
➡Cascading Deletes are painful
➡Choose the controlling relationship
➡inverse=true
➡Else double queries, inefficient queries
➡Does it make sense?
➡Supporting methods for bi-directional linkage
➡Supporting methods for un-linkages
AVOID BI-DIRECTIONAL,
IF POSSIBLE!
BETTER Relationships
➡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()
UNDERSTAND THE 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()
UNDERSTAND THE HIBERNATE SESSION
DB Sync
Insertions in order
updates
Collection deletions
collection deletion, updates, inserts
collection insertions
deletions in order
UNDERSTAND THE HIBERNATE SESSION
➡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 raw transactions
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
TRANSACTION DEMARCATION
TRANSACTION DEMARCATION
TRANSACTION DEMARCATION
➡Don’t do it!
➡Breaks the link to the Hibernate Session
➡Relationships will fail if not lazy loaded
➡entityMerge()
➡Store ID’s or data instead, then inflate the entities
AVOID SCOPING ENTITIES
➡Don’t go cache crazy, develop a strategy
➡Misconception: Does not store CFC
➡Stores individual property values
➡Use distributed caches: ehcache, couchbase, redis
➡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()
CACHE
BOOSTING
CACHE
BOOSTING
CACHE
BOOSTING
➡The fastest gun in the galaxy!
➡Return array of structs
➡Why a full ORM Object graph?
➡Boost your APIs, stop converting queries/
array of objects to JSON HQL
MAPS
HQL
MAPS
When is HappyBox?
ORM was fast
Extensible way to finish
the remaining 20%
CF ORM was easier to use?
80% of API Querying
OO way to query
Auto build relationships
ORM
THOUGHTS?
Base ORM Service
Virtual ORM Service
Active Entity
Entity Populators
Validation
Event Handlers
DI/AOP
OVERVIEW
➡Service layer for any entity
➡OO Querying, caching, transactions
➡Dynamic finders, getters, counters
➡Object metadata & session management
➡Exposes more features from Hibernate
➡90% Foundation
BASE ORM
SERVICE
➡Extends Base ORM Services
➡Roots itself to a single entity = Less Typing
➡You can build the 10%
VIRTUAL
SERVICES
➡Active Record Pattern
➡Sweet validation integration
➡DI/AOP Available
ACTIVE
ENTITY
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
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
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