Glossary

What Is a ColdFusion Persistent Component?

Definition

A ColdFusion Persistent Component is a ColdFusion Component (CFC) that is mapped to a database table and managed by ColdFusion ORM (Object-relational mapping). Declaring a component as persistent tells ColdFusion to treat it as a database-backed entity—automatically handling CRUD operations, identity, relationships, and caching through Hibernate. Put simply: a persistent component is an object that ColdFusion knows how to store, retrieve, and relate to other objects without you writing raw SQL for every operation.


How It Works

Under the Hood: ColdFusion ORM and Hibernate

  • ColdFusion ORM is a layer on top of Hibernate, a mature Java ORM library.
  • When you mark a CFC with persistent="true", ColdFusion generates an entity mapping from the component and its cfproperty tags/metadata.
  • ORM handles:
    • Identity (primary keys, sequences, generated IDs).
    • Relationships (one-to-many, many-to-one, many-to-many).
    • Fetching strategies (lazy vs. eager loading).
    • Transactions and dirty checking (tracking changes to objects).
    • Caching (first-level session cache and optional second-level cache).

Lifecycle in a Request

  1. Your ColdFusion app starts with ORM enabled in Application.cfc.
  2. On first ORM access (or after an ORMReload()), ColdFusion builds mappings.
  3. You create or load entities with functions such as entityNew, entityLoad, entitySave, entityDelete.
  4. ORM keeps track of Object state in a session. When you save or commit a transaction, Hibernate generates SQL and syncs changes to the database.
See also  What Is a ColdFusion Function?

Syntax and Basic Example

Application Configuration (Application.cfc)

cfm
component {
this.name = “MyApp”;
this.datasource = “myDSN”;
this.ormEnabled = true;
this.ormSettings = {
dbcreate = “update”, // validate | update | create | dropcreate
cfclocation = [“model”], // folder(s) containing CFCs
logSQL = true
};
}

Defining a Persistent CFC (cfcomponent)

cfm










Using the Entity (cfscript)

cfm


user = entityNew(“User”);
user.setEmail(“alice@example.com”);
user.setPassword(“strongP@ssw0rd”);
entitySave(user); // INSERT

loaded = entityLoad(“User”, {email=”alice@example.com”}, true); // unique result
writeDump(loaded.getId()); // read ID

entityDelete(loaded); // DELETE

Key attributes to notice
  • persistent="true": marks the CFC as an ORM entity.
  • cfproperty with fieldtype="id": defines the primary key.
  • ormtype and column: map CF datatypes to DB columns.
  • Lifecycle functions like entitySave and entityLoad simplify persistence.

Relationships and Mappings

One-to-Many and Many-to-One Example

Order and OrderItem are classic related entities.

cfm














  • one-to-many on Order references many OrderItems.
  • many-to-one on OrderItem points back to Order via fkcolumn.
  • cascade="all-delete-orphan" ensures item rows are saved/removed with the parent entity.

Real-World Use Case: E‑commerce Order Management

An online store needs to create orders, attach items, and calculate totals. With Persistent components:

  • Create an Order entity with a generated orderNumber.
  • Create several OrderItem entities and associate them with the Order.
  • Persist the order in a single unit:

cfm


order = entityNew(“Order”);
order.setOrderNumber(“A100234”);

items = [];
arrayAppend(items, entityNew(“OrderItem”, {sku=”ABC-123″, qty=2, price=19.99}));
arrayAppend(items, entityNew(“OrderItem”, {sku=”XYZ-555″, qty=1, price=249.00}));

order.setItems(items);

transaction {
entitySave(order); // cascades to items
}

The ORM manages inserts, foreign keys, and cascades, removing a lot of boilerplate SQL and helping the team move faster.


Use Cases

  • Domain-driven apps where objects map closely to business entities (Users, Orders, Invoices).
  • Rapid CRUD development for admin dashboards.
  • Apps that benefit from lazy loading, relationship management, and transactional persistence.
  • Teams migrating from hand-written SQL to a more declarative data model.

Best practices

Modeling and Mapping

  • Prefer explicit table, column, and ormtype definitions for clarity.
  • Always define an ID property with a clear generator (e.g., native, identity, uuid).
  • Name relationships carefully; use fkcolumn to make DB constraints predictable.
See also  What Is ColdFusion Enterprise Edition?

Performance and Fetching

  • Default to lazy loading on collections; use eager="true" only when necessary.
  • Batch operations within cftransaction/transaction blocks to reduce round-trips.
  • Consider enabling second-level cache and query cache for read-heavy entities.

Validation and Security

  • Validate input before entitySave (e.g., email format, length checks).
  • Store password hashes, not plain text. Keep crypto in component methods to centralize logic.
  • Whitelist properties exposed to serialization to avoid leaking sensitive fields.

Operational Tips

  • Use ORMReload() during development to reflect mapping changes; avoid in production.
  • Control schema generation via dbcreate (e.g., validate in production).
  • Log SQL (logSQL=true) in dev/test to diagnose N+1 queries or inefficient fetch patterns.

Common pitfalls

  • Over-eager loading entire object graphs, causing Performance issues.
  • Forgetting to define indexes/constraints in the database, resulting in Slow queries.
  • Relying on dbcreate=create in production, accidentally dropping tables.
  • Mixing raw SQL and ORM without clear boundaries, leading to stale caches or inconsistent transactions.
  • Not handling lazy initialization outside an ORM session (e.g., after the request ends).

Comparison: Persistent Component vs. Regular CFC

  • Persistent CFC:

    • Declared with persistent="true".
    • Mapped to a database table; managed by ORM/Hibernate.
    • Lifecycle and relationships are automatically handled.
    • Accessed with helpers like entityLoad, entitySave.
  • Regular CFC:

    • Plain object without ORM metadata.
    • No automatic persistence; you write queries yourself.
    • Full control over SQL but more boilerplate and manual mapping.

Pros and cons

  • Pros:

    • Faster development for CRUD and relational data.
    • Consistent domain model; less boilerplate SQL.
    • Built-in transactions, caching, and lifecycle management.
  • Cons:


Key Points

  • A ColdFusion persistent component is an ORM-managed entity mapped to a database table.
  • Use persistent="true" and cfproperty metadata to define identity and fields.
  • Enable ORM in Application.cfc with this.ormEnabled=true.
  • Operate via helpers like entityNew, entityLoad, entitySave, and entityDelete.
  • Tune performance with lazy loading, transactions, and caching.
See also  What Is CFLOOP in ColdFusion?

Troubleshooting and Debugging

  • Turn on logSQL and review Server logs for generated queries.
  • Use ORMReload() after mapping changes during development.
  • Diagnose N+1 query issues by checking when collections are fetched; adjust lazy/eager settings.
  • Validate that cfclocation points to all entity folders.
  • Confirm datasource permissions (create/update) match your dbcreate mode.

Security Considerations

  • Secure sensitive fields (e.g., passwordHash) and avoid exposing them via APIs.
  • Use transactions to prevent partial writes that could corrupt state.
  • Apply parameterized queries when mixing ORM with raw SQL, and rely on ORM’s parameterization for entity operations.
  • Validate and sanitize inputs before saving entities to mitigate injection or logic errors.

FAQ

What is the difference between ColdFusion ORM and Hibernate?

ColdFusion ORM is an abstraction layer built into Adobe ColdFusion and powered by Hibernate under the hood. You configure mappings with CFC metadata instead of writing Hibernate XML or annotations directly, but the persistence engine is Hibernate.

Do I still need SQL if I use Persistent components?

Often less, but not none. ORM covers typical CRUD, relationships, and many queries. For complex reports or highly optimized queries, you may still use raw SQL or HQL, or call stored procedures alongside ORM.

How do I handle Database schema changes with ORM?

Use this.ormSettings.dbcreate:

  • validate for production (checks mappings against the schema).
  • update for dev/test to apply incremental changes.
  • Avoid create or dropcreate in production. Use migrations or DBA-managed scripts for safety.

Can I control when related entities are loaded?

Yes. Use lazy="true" (default) to defer loading until accessed, or eager="true" to fetch immediately. Choose per relationship and tune based on usage to avoid N+1 queries.

What happens if I change an entity and don’t call entitySave?

If the entity is attached to the current ORM session and the request commits a transaction, Hibernate’s dirty checking can flush changes automatically. To be explicit and predictable, call entitySave within a transaction for important changes.

About the author

Aaron Longnion

Aaron Longnion

Hey there! I'm Aaron Longnion — an Internet technologist, web software engineer, and ColdFusion expert with more than 24 years of experience. Over the years, I've had the privilege of working with some of the most exciting and fast-growing companies out there, including lynda.com, HomeAway, landsofamerica.com (CoStar Group), and Adobe.com.

I'm a full-stack developer at heart, but what really drives me is designing and building internet architectures that are highly scalable, cost-effective, and fault-tolerant — solutions built to handle rapid growth and stay ahead of the curve.