Object Oriented Pagination in ColdFusion

There are various ways to perform pagination in ColdFusion, but I thought I would offer a few additional thoughts to the subject, including an object oriented approach to handling the results.

Getting the data

The first step is in getting the data. There seem to be many solutions to this, but the approach I will use here seems to be a nice approach that only returns the specific records for the page (rather than returning the entire record set on each query) and is hopefully not too database specific. Suppose we have a Person table with columns personId, firstName and lastName and we want to display 30 records per page ordered by last name. In this example we will display page 3 of the data.

The following query will return exactly the records we need.

<cfset pageSize = 30>
<cfset page = 3>
<cfset recordsToSkip = (page - 1) * pageSize>
 
<cfquery name=" personData" datasource="sales">
	select top #pageSize# *
	from Person
	where
		personId not in (
			select top #recordsToSkip# personId
			from Person
			order by lastName
		)
	order by lastName
</cfquery>

Filtering the data

Suppose we also have an “isActive” flag in this table, and we want to limit the result to only active records:

<cfset pageSize = 30>
<cfset page = 3>
<cfset recordsToSkip = (page - 1) * pageSize>
 
<cfquery name=" personData" datasource="sales">
	select top #pageSize# *
	from Person
	where
		isActive = 1
		and personId not in (
			select top #recordsToSkip# personId
			from Person
			where isActive = 1
			order by lastName
		)
	order by lastName
</cfquery>

Notice that the subquery must order and limit the records to the same as the outer query.

Removing Duplicate Code

You could also use variables for the where and order by clause to reduce duplication in the code:

<cfset pageSize = 30>
<cfset page = 3>
<cfset recordsToSkip = (page - 1) * pageSize>
 
<cfsavecontent variable="where">
	and isActive = 1 
</cfsavecontent>
 
<cfsavecontent variable="orderBy">
	order by lastName
</cfsavecontent>
 
<cfquery name="personData" datasource="sales">
	select top #pageSize# *
	from Person
	where
		1=1
		#where#
		and personId not in (
			select top #recordsToSkip# personId
			from Person
			where
				1=1
				#where#
			#orderBy#
		)
	#orderBy#
</cfquery>

Getting the count of total records

The above query only returns the page of data you need, but does not provide you with the total number of records in your result – which you need to know to know how many pages you have in total. So you will need to issue a second SQL command to get the record count. This is the same query, but with a count (*) instead:

<cfquery name="personCount" datasource="sales">
	select count(*) as num
	from Person
	where
		1=1
		#whereClause#
</cfquery>
<cfset recordCount = personCount.num>

Using a Gateway Component

Query such as these can be placed inside a Gateway object.

In this example we implement two functions: findPeopleByPage() and getPeopleCount(), in addition to passing a Datasource object to the init() function.

Notice that we pass in the where and orderBy as parameters to the functions.

<cfcomponent output="false">
 
	<cfset variables.datasource = 0>
 
	<cffunction name="init" output="false">
		<cfargument name="datasource">
		<cfset variables.datasource = arguments.datasource>
	</cffunction>
 
	<cffunction name="findPeopleByPage" output="false">
		<cfargument name="page">
		<cfargument name="pageSize">
		<cfargument name="where" default="">
		<cfargument name="orderBy" default="">
		<cfset var personData = 0>
		<cfquery
			name="personData"
			datasource="#variables.datasource.getName()#">
			<!--- Page query here. --->
		</cfquery>
		<cfreturn personData>
	</cffunction>
 
	<cffunction name="getPeopleCount" output="false">
		<cfargument name="where" default="">
		<cfset var personCount = 0>
		<cfquery
			name="personCount"
			datasource="#variables.datasource.getName()#">
			<!--- Count query here. --->
		</cfquery>
		<cfreturn personCount.num>
	</cffunction>
 
</cfcomponent>

In this case, the where clause and order by are just passed in as SQL strings, but this could perhaps be improved further by passing in data structures such as structs or lists.

Pagination calculations

We need a couple of numbers for our pagination:

<!--- Provided by the application, such as via a URL parameter. --->
<cfset page = url.page> 
 
<!--- Part of the application configuration. --->
<cfset pageSize = 30>
 
<!--- Provided by the getPeopleCount() function. --->
<cfset totalRecords = getPeopleCount()>
 
<!--- Calculate total pages available. --->
<cfset totalPages = int(totalRecords / pageSize)>
<cfif totalPages mod pageSize gt 0>
	<cfset totalPages = totalPages + 1>
</cfif>
 
<!--- Calculate previous page. --->
<cfset previousPage = max( page-1, 1 )>
 
<!--- Calculate next page. --->
<cfset nextPage = min( page+1, totalPages )>

Using a Paginator Component

Taking this further, the actual handling of the pages could be done in a Paginator component. The paginator manages the where clause, order by and page size for you.

Here, we initialise the Paginator with the gateway.

<cfcomponent name="PersonPaginator" output="false">
 
	<cfset variables.personGateway = 0>
	<cfset variables.where = "">
	<cfset variables.orderBy = "">
	<cfset variables.pageSize = "">
 
	<cfset variables.page = 0>
	<cfset variables.totalRecords = "">
 
	<cffunction name="init" output="false">
		<cfargument name="personGateway">
		<cfargument name="pageSize">
		<cfargument name="where">
		<cfargument name="orderBy">
		<cfset variables.personGateway = arguments.personGateway>
		<cfset variables.pageSize = arguments.pageSize>
		<cfset variables.where = arguments.where>
		<cfset variables.orderBy = arguments.orderBy>
	</cffunction>
 
	<cffunction name="getPage" output="false">
		<cfargument name="page">
		<cfset var personData = 0>
		<cfset variables.page = arguments.page>
		<cfset personData = 
				variables.personGateway.findPeopleByPage(
					variables.page,
					variables.pageSize,
					variables.where,
					variables.orderBy
				)>
		<cfreturn personData>
	</cffunction>
 
	<cffunction name="getCount" output="false">
		<cfif len(variables.totalRecords) eq 0>
			<cfset variables.totalRecords = 
					variables.personGateway.getPeopleCount(
						variables.pageSize,
						variables.where,
						variables.orderBy
					)>
		</cfif>
		<cfreturn variables.totalRecords>
	</cffunction>
 
	<cffunction name="getNumberOfPages" output="false">
		<cfset var totalRecords = getCount()>
		<cfset var totalPages = int(totalRecords / variables.pageSize)>
		<cfif totalRecords mod variables.pageSize gt 0>
			<cfset totalPages = totalPages + 1>
		</cfif>
		<cfreturn totalPages>
	</cffunction>
 
	<cffunction name="getNextPageNumber" output="false">
		<cfset var totalPages = getNumberOfPages()>
		<cfset var nextPage = min( 
						variables.page + 1, 
						totalPages )>
		<cfreturn nextPage>
	</cffunction>
 
	<cffunction name="getPreviousPageNumber" output="false">
		<cfset var totalPages = getNumberOfPages()>
		<cfset var previousPage = max( 
						variables.page - 1, 
						1 )>
		<cfreturn previousPage>
	</cffunction>
 
</cfcomponent>

An example of using our paginator:

<!--- Create our paginator component. --->
<cfset paginator = createObject("component","PersonPaginator")>
 
<!--- 
Initialise the paginator indicating we want
a) 30 records per page
b) only active people
c) ordered by last name then first name
--->
<cfset paginator.init(
			personGateway,
			30,
			"and isActive=1",
			"order by lastName asc, firstName asc"
		)>

Set up our pagination variables.

<!--- Let's assume the page is pased in via the URL. --->
<cfparam name="url.page" default="1">
 
<!--- Calculate our page variables. --->
<cfset page = url.page>
<cfset pageData = paginator.getPage(page)>
<cfset totalPages = paginator.getNumberOfPages()>
<cfset prevPage = paginator.getPreviousPageNumber()>
<cfset nextPage = paginator.getNextPageNumber()>

Display the page of data

<!--- Display the data --->
<cfloop query="pageData">
	<cfoutput>#lastName#, #firstName#<br /></cfoutput>
</cfloop>

Display the nagivator that lets you move from page to page.

<cfoutput>
<!--- Display the page navigator --->
<a href="page.cfm?page=#prevPage#">Previous</a>
Page #page# of #totalPages#
<a href="page.cfm?page=#nextPage#">Next</a>
</cfoutput>

Wrapping up

For extremely large record sets you may need to seek a more efficient solition, but this should be fine if you are dealing with thousands (or even a few hundred thousand) records.

This entry was inspired by a PHP thread on pagination (
http://www.phpbuilder.com/board/showpost.php?p=10668964&postcount=13
),

This entry was posted in OOP and tagged , . Bookmark the permalink. Both comments and trackbacks are currently closed.

22 Comments

  1. Posted November 3, 2007 at 11:09 am | Permalink

    With Ms-SQL 2005 / Oracle, you can use ROW_NUMBER() for much better performance:

    with tbl as
    (
    select u.lastName, u.firstName
    ROW_NUMBER() over (order by u.lastName, u.firstName) as RowNum
    from users u
    )
    select * from tbl
    where
    RowNum between @startRow and @endRow
    order by
    lastName, firstName

    Cheers.

  2. Posted November 3, 2007 at 12:06 pm | Permalink

    Hi Rob, thanks for the tip!

  3. Posted November 5, 2007 at 3:07 pm | Permalink

    @Kevan,

    Nice code. Ben Nadel and I have had similar discussions recently on pagination, and here’s what I’m currently using. ;)

    http://cfzen.instantspot.com/blog/index.cfm/2007/10/11/Paginating-Records-in-CF-with-One-SQL-Server-2005-call

  4. Posted November 7, 2007 at 2:24 am | Permalink

    Hi Aaron, thanks for the link.

  5. Posted January 26, 2008 at 5:42 am | Permalink

    Update: Fixed an error in the code that returned the count of people.

  6. Posted March 28, 2008 at 6:34 am | Permalink

    What a truly wonderful post Kevan!!

    I am just about to build my pagination system into a huge project I’m working on but was having real problems working out how to handle this in a OO way and integrate it with Transfer.

    This post was pretty much written for me as you cover just about everything I need. I was going to create a DataTools singleton which would handle pagination but quite like your pagination cfc which I could just inject into my gateways as needed. I should be able to make it quite generic with perhaps standard API functions in each gateway..

    Thanks again for this excellent post – spot on.

  7. Posted March 28, 2008 at 1:44 pm | Permalink

    Thanks James!

  8. Dani
    Posted June 14, 2008 at 11:12 pm | Permalink

    Hello Kevan, thanks for the tutorial.
    However, I’m having some issues with the code, I’m getting a syntax error when I try to run it.

    Here is my code:

    <cfloop query = "getNames">

    <cfset pageSize = 30>
    <cfset page = #page# + 1>
    <cfset recordsToSkip = (#page# – 1) * #pageSize#>

    <cfquery name="getLabour" datasource="andes">
    SELECT top #pageSize# * FROM control_lab
    where conID not in(
    select top #recordsToSkip# conID
    from control_lab
    and proID = ‘#URL.proID#’
    AND empID = ‘#getNames.empID#’
    order by proDate desc
    )
    and proID = ‘#URL.proID#’
    AND empID = ‘#getNames.empID#’
    order by proDate desc

    </cfquery>

    Any idea?
    Thank you very much

    Dani

  9. Dani
    Posted June 14, 2008 at 11:19 pm | Permalink

    Correction to my previous code:

    <cfset pageSize = 30>
    <cfset page = #page# + 1>
    <cfset recordsToSkip = (#page# – 1) * #pageSize#>

    <cfquery name="getLabour" datasource="andes">
    SELECT top #pageSize# * FROM control_lab
    where conID not in(
    select top #recordsToSkip# conID
    from control_lab
    order by proDate desc
    )
    and proID = ‘#URL.proID#’
    AND empID = ‘#getNames.empID#’
    order by proDate desc

    </cfquery>

    Still getting the syntax error:

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’30 * FROM control_lab where conID not in( select top 0 conID from con’ at line 1

  10. Posted June 15, 2008 at 2:00 am | Permalink

    Hi Dani

    It looks like MySQL does not support the TOP syntax. From the article here – http://www.anticlue.net/archives/000321.htm – looks like you need to use the LIMIT command.

    My guess would be that it goes something like this:

    <cfquery name="personData" datasource="sales">
    select *
    from Person
    where
    personId not in (
    select personId
    from Person
    LIMIT #recordsToSkip#
    )
    LIMIT #pageSize#
    order by lastName
    </cfquery>

    But unfortunately I don’t have a copy of MySQL to try it out.

  11. Posted June 15, 2008 at 2:06 am | Permalink

    Oops, I forgot the ORDER BY in the subquery, and let’s use your code instead:

    <cfset pageSize = 30>
    <cfset page = page + 1>
    <cfset recordsToSkip = (page – 1) * pageSize>

    <cfquery name="getLabour" datasource="andes">
    select * from control_lab
    where conID not in (
    select conID
    from control_lab
    order by proDate desc
    LIMIT #recordsToSkip#
    )
    and proID = ‘#URL.proID#’
    and empID = ‘#getNames.empID#’
    order by proDate desc
    LIMIT #pageSize#
    </cfquery>

    Hopefully that is closer to a working query.

  12. Dani
    Posted June 15, 2008 at 9:44 pm | Permalink

    Hello Kevan, thanks so much for taking the time to check and edit the code.
    According to the error page I get now, LIMIT within a subquery is not accepted.
    Maybe if I tell you what I’m trying to do you can have an extra idea.

    I have a report generated with cfdocument that lists the daily labour activity in a particular project by employee (for a construction company). All the employees that were working on the project are listed in this report in their on page (i’m doing a page break at the end of the employees’s loop).
    With small projects works ok because the activity for each employee fits in one page. But for large projects, there will be a record of information that will be cut off when the cfoutput tag reaches the bottom of the page.
    That’s why i need to determine the max rows to print per page per employee.

    Thanks again!!

    dani

  13. Posted June 16, 2008 at 4:00 am | Permalink

    Hi Dani

    Looks like this may be simpler in MySQL than in MSSQL2000; we don’t need the subquery. Looking up the LIMIT syntax – http://dev.mysql.com/doc/refman/5.0/en/select.html – looks like we get something like:

    <cfset pageSize = 30>
    <cfset page = page + 1>
    <cfset recordsToSkip = (page – 1) * pageSize>

    <cfquery name="getLabour" datasource="andes">
    select *
    from control_lab
    where proID = ‘#URL.proID#’
    and empID = ‘#getNames.empID#’
    order by proDate desc
    limit #recordsToSkip#, #pageSize#
    </cfquery>

    I haven’t tested this but, who knows, it might just work.

  14. Mescalito2
    Posted July 14, 2009 at 7:59 am | Permalink

    Hi! Thanks for your post, it has been very useful. I want to share some bugs that I have found:

    1. I really don’t understand how do you use/call the "gateway", what I did is to extend from the "gateway" in the peoplePaginator component

    ?????? no idea how to use this: <cfset variables.peopleGateway = arguments.peopleGateway>

    My solution: <cfcomponent extends="peoplegateway" output="false">

    2. You named the component "PeoplePaginator" but you are calling it as a "PersonPaginator". That is ambigous and it doesn’t work (at least for me)

    3. In getNumberOfPages function, when you are doing the "mod" calc, you are using the wrong var

    WRONG: <cfif totalPages mod variables.pageSize gt 0>
    GOOD: <cfif totalRecords mod variables.pageSize gt 0>

    4. On PeoplePaginator init, I think you need to pass the current page number as an argument

    +++ when using the object +++
    <cfparam name="url.page" default="1">
    <cfset page = url.page>

    <cfset paginator.init(
    10,
    "and isActive=1",
    "order by lastName asc, firstName asc",
    page <<<—- This is the new parameter
    )>
    +++++

    === init function within the component ===
    <cffunction name="init" output="false">
    <cfargument name="pageSize">
    <cfargument name="where">
    <cfargument name="orderBy">
    <cfargument name="currentPageNumber"> <<<—- This is the new argument
    <cfset variables.pageSize = arguments.pageSize>
    <cfset variables.where = arguments.where>
    <cfset variables.orderBy = arguments.orderBy>
    <cfset variables.page = arguments.currentPageNumber> <<<—- This is the new argument
    </cffunction>
    ======

    5. This function is not returning a value getNextPageNumber

    6. Here you have to put the output coldfusion tags:
    <cfoutput><a href="test.cfm?page=#prevPage#">Previous</a>
    Page #page# of #totalPages#
    <a href="test.cfm?page=#nextPage#">Next</a></cfoutput>

    I think there are others errors but I dind’t track them. If you want to download the code (working) you can do it from: http://dev.dualcredit.itap.purdue.edu/mescalito2-paginator.rar
    and by the way, remember to change the datasources

  15. Mescalito2
    Posted July 14, 2009 at 11:22 am | Permalink

    Thanks!

  16. Posted July 15, 2009 at 4:29 am | Permalink

    Mescalito2, thanks for such a thorough review and corrections. Regarding your points:

    1. The gateway would be used something like this:

    <!— First create the gateway object separately —>
    <cfset personGateway = createObject("component","PersonGateway").init(dsn)>

    <!— Then create the pagination and provide the gateway as a parameter —>
    <cfset paginator = createObject("component","PersonPaginator").init(
    personGateway,
    30,
    "and isActive=1",
    "order by lastName asc, firstName asc"
    )>

    This type of relationship is called composition (the gateway is "composed" inside the paginator). Composition is a generally preferred relationship over inheritance (where the paginator extends the gateway).

    Inside the paginator, whenever you need to use the gateway you would refer to variables.personGateway

    2. It should be named PersonPaginator. Thanks, I have fixed this.

    3. Thanks, fixed.

    4. I can see what you are getting at. What was missing was the page should have been set inside the getPage() function and the page should have been initialised to zero. Not sure about setting the current page on init() and then /also/ passing it in to the getPage() function. I think I will leave it out of the init() for now.

    5. Thanks, fixed.

    6. Yes, would be nicer to include the cfoutput’s

    Thanks for letting me know about this swarm of typos!

  17. Thangapandyan
    Posted September 12, 2011 at 4:26 am | Permalink

    hi,
    really i don’t know how to use the paginator example ,can you explain what are content come under .cfc pages and .cfm pages

  18. Posted September 12, 2011 at 10:58 am | Permalink

    Hi Thangapandyan, sorry not sure what you are asking. All of the cfc and cfm code is in the article.

  19. ThangapandyanV
    Posted September 12, 2011 at 11:20 am | Permalink

    Hi,
    How can i configure the gateway in coldfusion administrator.

  20. Posted September 12, 2011 at 11:26 am | Permalink

    Hi Thangapandyan, this is not an event gateway that you configure in coldfusion administrator. This cfc is named a gateway keeping in line with the gateway design pattern (http://martinfowler.com/eaaCatalog/gateway.html). It’s just a regular cfc.

  21. ThangapandyanV
    Posted September 12, 2011 at 11:36 am | Permalink

    Hi,
    i have two coldfusion component files using for to arrive pagination in my application,file name called personGateway.cfc and personpaginator.cfc,
    first file name contains below details,

    select top #pageSize# *
    from mstproperty
    where
    1=1
    #where#
    and pid not in (
    select top #recordsToSkip# pid
    from mstproperty
    where
    1=1
    #where#
    #orderBy#
    )
    #orderBy#

    select count(*) as num
    from mstproperty
    where
    1=1
    #where#

    and second file contains below details,

    and i a am using the below file for calling the coldfusion component file to my application for arrive the pagination in my application,file name called pagination1.cfm

    and marketid = 3 and propertytypeid = 2 and statusid not in (1,7)

    order by propertyname

    #lastName#, #firstName#


    Previous
    Page #page# of #totalPages#
    Next

    but when i ran the above code i got the below error

    The web site you are accessing has experienced an unexpected error.
    Please contact the website administrator.

    The following information is meant for the website developer for debugging purposes.

    Error Occurred While Processing Request
    Local variable personData on line 25 must be grouped at the top of the function body.

    The error occurred in D:\web\Oconnordata\Pagination1.cfm: line 16

    14 :
    15 :
    16 :
    17 :
    18 :

    ——————————————————————————–

    Resources:
    Check the ColdFusion documentation to verify that you are using the correct syntax.
    Search the Knowledge Base to find a solution to your problem.

    Browser Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; GTB6.6; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; InfoPath.2; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E; MSN OptimizedIE8;ENIN)
    Remote Address 127.0.0.1
    Referrer
    Date/Time 12-Sep-11 05:00 PM

    Stack Trace (click to expand)
    at cfPagination12ecfm889454527.runPage(D:\web\Oconnordata\Pagination1.cfm:16)

    coldfusion.compiler.ASTvariableDefinition$VarPositionException: Local variable personData on line 25 must be grouped at the top of the function body.
    at coldfusion.compiler.ASTvariableDefinition.checkCfscript(ASTvariableDefinition.java:158)
    at coldfusion.compiler.ASTvariableDefinition.checkPosition(ASTvariableDefinition.java:116)
    at coldfusion.compiler.ASTvariableDefinition.register(ASTvariableDefinition.java:87)
    at coldfusion.compiler.SemanticAnalyzer.transform(SemanticAnalyzer.java:196)
    at coldfusion.compiler.Treewalker.postorder(Treewalker.java:86)
    at coldfusion.compiler.Treewalker.postorder(Treewalker.java:27)
    at coldfusion.compiler.Treewalker.postorder(Treewalker.java:27)
    at coldfusion.compiler.Treewalker.postorder(Treewalker.java:27)
    at coldfusion.compiler.NeoTranslator.translateJava(NeoTranslator.java:307)
    at coldfusion.compiler.NeoTranslator.translateJava(NeoTranslator.java:119)
    at coldfusion.runtime.TemplateClassLoader$1.fetch(TemplateClassLoader.java:310)
    at coldfusion.util.LruCache.get(LruCache.java:180)
    at coldfusion.runtime.TemplateClassLoader$TemplateCache.fetchSerial(TemplateClassLoader.java:254)
    at coldfusion.util.AbstractCache.fetch(AbstractCache.java:58)
    at coldfusion.util.SoftCache.get(SoftCache.java:81)
    at coldfusion.runtime.TemplateClassLoader.findClass(TemplateClassLoader.java:476)
    at coldfusion.runtime.RuntimeServiceImpl.getFile(RuntimeServiceImpl.java:752)
    at coldfusion.runtime.RuntimeServiceImpl.resolveTemplatePath(RuntimeServiceImpl.java:733)
    at coldfusion.runtime.TemplateProxyFactory.getTemplateFileHelper(TemplateProxyFactory.java:1377)
    at coldfusion.runtime.TemplateProxyFactory.resolveName(TemplateProxyFactory.java:1330)
    at coldfusion.cfc.ComponentProxyFactory.getProxy(ComponentProxyFactory.java:38)
    at coldfusion.runtime.ProxyFactory.getProxy(ProxyFactory.java:65)
    at coldfusion.runtime.CFPage.createObjectProxy(CFPage.java:4638)
    at coldfusion.runtime.CFPage.CreateObject(CFPage.java:4483)
    at cfPagination12ecfm889454527.runPage(D:\web\Oconnordata\Pagination1.cfm:16)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:196)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:483)
    at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
    at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:288)
    at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
    at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
    at coldfusion.filter.PathFilter.invoke(PathFilter.java:86)
    at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:27)
    at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
    at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
    at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
    at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
    at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
    at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
    at coldfusion.CfmServlet.service(CfmServlet.java:198)
    at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
    at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
    at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
    at jrun.servlet.FilterChain.service(FilterChain.java:101)
    at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
    at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
    at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
    at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
    at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
    at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)
    at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
    at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)
    at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

    kindly help us to resolve this.

    Thanks in advance.

  22. Posted September 13, 2011 at 10:10 am | Permalink

    Hi Thangapandyan

    It looks like there is a typo in the getPage function. I’ve fixed it in the post. Rather than this:


    <cfset variables.page = arguments.page>
    <cfset var personData = ...>

    it should have read:


    <cfset var personData = 0>
    <cfset variables.page = arguments.page>
    <cfset personData = ...>