Blog

cbORM v2.2.0 Released!

Luis Majano August 23, 2019

Spread the word

Luis Majano

August 23, 2019

Spread the word


Share your thoughts

We are so excited to bring you yet another minor release for our cborm project to version 2.2. We have fine tuned our module with some cool new features and some major improvements. So let's start with our orm adventure by installing or updating.

Install or Update

To get started with cborm, just install it via CommandBox: box install cborm. To update your current install just run a update cborm and off you go.

New Documentation Book

We have completely overhauled the documentation for this module and converted it to a comprehensive book. The new book contains a refreshed look, better categorization, improved structure and some very nice intros to working with Basic CRUD with services and Basic CRUD with Active Entity and all the way to advanced criteria queries.

 

 

What is cborm

The cborm module is a module that will enhance your experience when working with the ColdFusion ORM powered by Hibernate. It will not only enhance it with dynamic goodness but give you a fluent and human approach to working with Hibernate

  • Service Layers with all the methods you could probably think off to help you get started in any project
  • Virtual service layers so you can create virtual services for any entity in your application
  • ActiveEntity our implementation of Active Record for ORM
  • Fluent queries via Hibernate's criteria and detached criteria queries with some Dynamic CFML goodness
  • Automatic transaction demarcation for save and delete operations
  • Dynamic finders and counters for expressive and fluent shorthand SQL
  • Automatic Java casting
  • Entity population from json, structs, xml, and queryies including building up their relationships
  • Entity validation via cbValidation
  • Includes the Mementifier project to produce memento states from any entity, great for producing JSON
  • Ability for finders and queries to be returned as Java streams using our cbStreams project.

 

# A quick preview of some functionality

var book = new Book().findByTitle( "My Awesome Book" );
var book = new Book().getOrFail( 2 );
new Book().getOrFail( 4 ).delete();
new Book().deleteWhere( isActive:false, isPublished:false );

property name="userService" inject="entityService:User";

return userService.list();
return userService.list( asStream=true );

var count = userService.countWhere( age:20, isActive:true );
var users = userService.findAllByLastLoginBetween( "01/01/2019", "05/01/2019" );

userService
    .newCriteria()
    .eq( "name", "luis" )
    .isTrue( "isActive" )
    .getOrFail();

userService
    .newCriteria()
    .isTrue( "isActive" )
    .joinTo( "role" )
        .eq( "name", "admin" )
    .asStream()
    .list();

userService
    .newCriteria()
    .withProjections( property="id,fname:firstName,lname:lastName,age" )
    .isTrue( "isActive" )
    .joinTo( "role" )
        .eq( "name", "admin" )
    .asStruct()
    .list();

What's New With 2.2.0

This release not only has some bug fixes but several new features that pack a punch.

Major Features

 

Criteria Query Fluent If Statements - when()

How many times have you been dealing with if statements in order to add some restrictions into your criteria object? Many, this was the only way before, not anymore. So instead of doing something like the following:

c = newCriteria();

if( isBoolean( arguments.isPublished ) ){
  
	c.isEq( "isPublished", isPublished );

	// Published eq true evaluate other params
    if( isPublished ){
        c.isLt( "publishedDate", now() )
        .$or( c.restrictions.isNull( "expireDate" ), c.restrictions.isGT( "expireDate", now() ) )
        .isEq( "passwordProtection","" );
    }

}

if( !isNull( arguments.showInSearch ) ){
	c.isEq( "showInSearch", showInSearch );
}


return c.list();

This looks like normal code, but we can do a more functional approach by introducing the when() function:

/**
* @test The boolean evaluation
* @target The closure to execute if test is true
*/
when( boolean test, function target )

This function takes in as the first argument a boolean value, if the value is true, then the target closure will be called for you and the criteria will be passed via the arguments scope:

newCriteria()
    .when( isBoolean( arguments.isPublished ), function( c ){
        // Published bit
        c.isEq( "isPublished", isPublished )
        	.when( isPublished, function( c ){
        		c.isLt( "publishedDate", now() )
	            .$or( c.restrictions.isNull( "expireDate" ), c.restrictions.isGT( "expireDate", now() ) )
	            .isEq( "passwordProtection","" );
        	} )
    } )
  .when( !isNull( arguments.showInSearch ), function( criteria ){	
  	c.isEq( "showInSearch", showInSearch );
   } )
  .list()

This construct will help you create more fluent designs when building criteria queries, enjoy!

 

PeekaBoo! - peek()

We have also enhanced the criteria queries with a peek() function which allows you to peek in the current position of the criteria build up. This allows you to debug or inspect the SQL/HQL inside the criteria at that point in time. You can use it for sending debug data or logging, or auditing.

/**
* @target the closure to execute, the criteria is passed as an argument
*/
peek( target )

Enjoy your peekaboo function!

newCriteria()
    .when( isBoolean( arguments.isPublished ), function( c ){
        // Published bit
        c.isEq( "isPublished", isPublished )
        	.when( isPublished, function( c ){
        		c.isLt( "publishedDate", now() )
	            .$or( c.restrictions.isNull( "expireDate" ), c.restrictions.isGT( "expireDate", now() ) )
	            .isEq( "passwordProtection","" );
        	} )
    } )
  .peek( function( c ){
      systemOutput( "HQL after publish: #criteria.getSql()# ");
  } )
  .when( !isNull( arguments.showInSearch ), function( criteria ){	
  	c.isEq( "showInSearch", showInSearch );
   } )
   .peek( function( c ){
      systemOutput( "HQL before listing: #criteria.getSql()# ");
  } )
  .list()

 

ValidateOrFail

We have added a new function on the ActiveEntity object to assist with validations. The validateOrFail() function will allow you to validate the entity and if it validates it just returns the instance of the entity for a nice fluent design. However, if the validation fails, it throws a ValidationException and the errors are passed to the exception object via the extendedInfo key. You can then deal with the exception as needed.

getInstance( "User" )
    .populate( rc )
    .validateOrFail()
    .save();

 

Release Notes

  • Features: New function for criteria query when( boolean, target ) that you can use to build functional criterias without the use of if statements.
  • Feature: Missing nullValue() is BaseBuilder class
  • Feature: Added new criteria query peek( closure ) function to allow for peeking into the building process. Pass in your closure that receives the criteria and interact with it.
  • Feature: Added a validateOrFail() to the active entity, which if the validation fails it will throw an exception or return back to you the same entity validated now.
  • Improvement: Better documentation for deleteById() since it does bulk deletion, which does not do any type of cascading.
  • Improvement: isValid() in active entity missing includeFields argument
  • Improvement: Timeout hints for criteria builder
  • Improvement: Updated exception type for criteria builder get()
  • Bug: ACF2016 issues with elvis operator.
  • Bug: getOrFail() had an invalid throw statement

Add Your Comment

Recent Entries

CBWIRE 3.0.0 Released

CBWIRE 3.0.0 Released

We are very excited to announce the release of version 3 of CBWIRE, our ColdBox module that makes building modern, reactive apps a breeze. This version brings with it a new component syntax, 19 enhancements and bug fixes, and improved documentation. Our biggest goal with this release was to improve the developer experience and to provide a low barrier to entry to getting started with CBWIRE.

Grant Copley
Grant Copley
May 22, 2023
ColdBox 7.0.0 Released

ColdBox 7.0.0 Released

Introducing ColdBox 7: Revolutionizing Web Development with Cutting-Edge Features and Unparalleled Performance

We are thrilled to announce the highly anticipated release of ColdBox 7, the latest version of the acclaimed web development HMVC framework for ColdFusion (CFML). ColdBox 7 introduces groundbreaking features and advancements, elevating the development experience to new heights and empowering developers to create exceptional web applications and APIs.

Designed to meet the evolving needs of modern web development, ColdBox 7 boasts a range of powerful features that streamline the development process and enhance productivity. With its robust HMVC architecture and developer-friendly tools, ColdBox 7 enables developers to deliver high-performance, scalable, and maintainable web applications and APIs with ease.

Esme Acevedo
Esme Acevedo
May 16, 2023
TestBox v5.0.0 Released!

TestBox v5.0.0 Released!


We are excited to announced the release of Testbox version 5, which brings a host of new features and improvements for developers. TestBox is a powerful and flexible tool that helps developers write comprehensive BDD/TDD tests for their applications, ensuring code quality and reducing the likelihood of bugs and errors. With TestBox v5, developers can take advantage of new features such as batch code coverage testing, improved reporting capabilities, method spies, and better integration with other tools in the Ortus suite.

These new features make TestBox even more versatile and user-friendly, and provide developers with a powerful tool for building high-quality, reliable applications.

 

Luis Majano
Luis Majano
May 11, 2023