Duplicate Entry for key PRIMARY

160 views
Skip to first unread message

Jonathan Price

unread,
Mar 28, 2015, 9:49:41 PM3/28/15
to cf-or...@googlegroups.com
We recently started to implement a taffy backend for an application, and we’ve started seeing some "Duplicate Entry for key PRIMARY” errors. I’d like to layout the situation here and see if any of you can make suggestions about the way we’re proceeding. Obviously, if the reasons for the duplicate error are apparent, please chime in! But I’m really mining for some larger ‘Oh don’t do that because…’ or ‘You really shouldn’t do that…’ type of advice.

Directory structure more or less like this:
/ <!— Main CF App (non-mobile, regular website) —>

/cfc <!— Main CF App ORM —>

/api/rest/ <!— TAFFY dir —>

/model/services <!— DI1 dirs —>

/model/beans

The main app had been around for a while. The ‘DI1’ directories were initially just for use in the new taffy backend for a mobile app we’re developing for the same company. As they began requesting some of the same functionality in the main CF app, we just figured we’d use those same services in the new DI1 area. The main CF app hadn’t been developed using DI1 (or a framework for that matter), so we just added a DI1 bean factory to it’s Application file and pointed it to the same /model area used by Taffy. And everything worked. For a while.

Without having to display too much code for you, I’ll provide some pseudo-code to illustrate the service call that seems to be the culprit.

Here’s a service call:

function update(key numeric required, newStatus numeric required) {

set local.object = EntityLoad(‘Thing’, key, true);
local.object.setNewStatus(ARGUMENTS.newStatus);
local.object.save();

…do some other stuff in other services...

return read(local.object.getID());
}

There’s a create function that’s similar to update, slightly different logic. The ‘local.object.save()’ part is also of note as it appears to be where the hangup occurs.

Member function of Object

function save() {

history = EntityNew(“ObjectHistory”);
history.setStatus(this.getStatus());
… a few more sets…

EntitySave(this);

history.setObject(this);
EntitySave(history);
}

Keep in mind that we’re not using transactions anywhere here, so that may be alarm number one. I really don’t know. We’ve just been letting end of request do the flushing for us. There were some ormFlush calls in various places, but we pulled them all out during the process of trying to hunt this down.

So, where’s the problem? If you take one of these objects through all of it’s states strictly using the phone (through the Taffy interface), it works great. No problems. As soon as you start using the old application to move through some of these state changes (using the same /model/services), you’ll start to see the duplicate errors. Specifically, they stem around the save function above. As a temporary stopgap, we just removed the history bits - which allows usage from both the taffy and main application to work error free. But the fact that switching between the two causes the duplicate issue makes me worry that there’s an architectural problem with our layout. Like the Hibernate data between the two Application spaces is falling out of sync somehow.

Now, it would be crazy to hope for a full diagnosis based on this, but maybe something in this description will set off some alarms for someone?

Also, I’m guessing (though I admittedly have no idea) we should considering wrapping the guts of the update() call in a transaction? Is that how you typically do it? Are transactions necessary? Could we just use ormFlush in some places to achieve more or less the same results? Could the lack of transaction be the culprit in the Duplicate errors?

Thanks for any suggestions.








Cameron Childress

unread,
Mar 30, 2015, 10:29:13 AM3/30/15
to cf-or...@googlegroups.com
On Sat, Mar 28, 2015 at 9:49 PM, Jonathan Price wrote:
We recently started to implement a taffy backend for an application, and we’ve started seeing some "Duplicate Entry for key PRIMARY” errors

Show us your ORM config and show us the definition for the offending ORM entity, especially it's PK and FK definitions. Make sure any PKs have fieldtype="id" on them.

-Cameron
 
--
Cameron Childress
--
p:   678.637.5072
im: cameroncf

Cameron Childress

unread,
Mar 30, 2015, 10:57:12 AM3/30/15
to cf-or...@googlegroups.com
Other select comments inline...

On Sat, Mar 28, 2015 at 9:49 PM, Jonathan Price wrote:
Directory structure more or less like this:

I build a FW/1 app and Taffy app that share the same model as well as some configuration recently and this is what I did:

Includes shared in both Applicaiton.cfc files:
/approot/config/environmentSettings.cfm - Environmental switches
/approot/config/ormSettings.cfm - ORM Config

Includes for Taffy's Application.cfc:
/approot/config/api/applicationSettings.cfm - App.cfc's psudoconstructor
/approot/config/api/onApplicationStart.cfm - onApplicaitonStart()
/approot/config/api/onTaffyRequest.cfm - onTaffyRequest()
/approot/config/api/taffySettings.cfm - Taffy config

Includes for FW/1 Application.cfc:
/approot/config/app/applicationSettings.cfm - App.cfc's psudoconstructor
/approot/config/app/fw1Settings.cfm - FW/1 settings
/approot/config/app/setupApplication.cfm - setupApplication()
/approot/config/app/setupRequest.cfm - setupRequest()

Libraries:
/approot/libs/* - FW/1, DI/1, Taffy, ValidateThis, etc.

Model:
/approot/model/*.cfc - Some base objects that other CFCs in the model extend
/approot/model/beans/*.cfc - ORM entities
/approot/model/endpoints/*.cfc - Taffy endpoints
/approot/model/services/*.cfc - DI/1 managed services
/approot/model/util/*.cfc - CFCs such as encryption libraries etc
/approot/model/validators/*.cfc - Validatethis Validation Definitions

Taffy Web App
/approot/www/Application.cfc - Taffy (this is also the Apache site's Webroot for the Taffy api)

FW/1 Web App
/approot/appname/Application.cfc - App (this is also the Apache site's Webroot for the app)
/approot/appname/subsystems - Typical FW/1 Subsystems

I configured DI/1 to look at both the Endpoint and Services folders. the ORM config and environmental settings (dev vs prod) are shared in both App.cfc files, and the rest is different. I didn't group the Endpoints inside the API app folder since they are all CFCs too and I felt like they should be closer to the services in the filesystem. No other real reason.

Keep in mind that we’re not using transactions anywhere here, so that may be alarm number one.  I really don’t know.  We’ve just been letting end of request do the flushing for us.  There were some ormFlush calls in various places, but we pulled them all out during the process of trying to hunt this down.

I usually tell CF not to manage my ORM session and not to flush at request end. Then I make sure all SQL is in Services and I wrap all the service calls in a transaction with an explicit comit. In a Taffy endpoint that looks something like this (very stripped down) example:

<cfcomponent taffy:uri = "/v1/user/{userid}" >

<cffunction name = "post">
  <cfargument name="userid" type="string" required="true" hint="User's ID." />
  <cfargument name="name" type="string" required="true" hint="User's name." />

  <cfscript>
  transaction {
    local.foo = getUserService().get(arguments.userid); // entityLoad happens inside here
    local.foo.setName(arguments.name);
    local.foo.save(); // entitySave() is inside here
    transactionCommit();
  }
  </cfscript>

  <cfreturn rep(local.foo.getAsStruct()).withStatus(200) />
</cffunction>

</cfcomponent>

Also, remember you don't need the tractions unless you are saving data. Loading doesn't need a transaction wrapper.

I know that was more than you asked but maybe it's helpful? 

-Cameron

Puritan Paul

unread,
Mar 30, 2015, 2:30:17 PM3/30/15
to cf-or...@googlegroups.com
Sure thing.


<cfcomponent persistent="true" table="WebRequest">

    <cfproperty name="id" fieldtype="id" column="WebRequestID" generator="increment">
    <cfproperty 
    name="WebRequestStatus" 
        fieldtype="many-to-one" 
        cfc="WebRequestStatus" 
        fkcolumn="WebRequestStatusID">
    
    <cfproperty 
    name="ConsultType" 
        fieldtype="many-to-one" 
        cfc="ConsultType" 
        fkcolumn="ConsultTypeID">
    
    <cfproperty 
    name="VideoType" 
        fieldtype="many-to-one" 
        cfc="VideoType" 
        fkcolumn="VideoTypeID">
    
    <cfproperty name="VideoAddress" type="string">
    <cfproperty name="Phone" type="string">
    <cfproperty name="ConsultTimeStart" type="date">
    <cfproperty name="ConsultTimeEnd" type="date">
    <cfproperty name="PhysicianConsultation" type="boolean">
    
    <cfproperty 
    name="Patient" 
        fieldtype="many-to-one" 
        cfc="Patient" 
        fkcolumn="PatientID">

    <cfproperty 
        name="TOSAgreement" 
        fieldtype="one-to-one" 
        cfc="TOSAgreement" 
        fkcolumn="TOSAgreementID">

    <cfproperty 
        name="CudatelCall" 
        fieldtype="one-to-one" 
        cfc="CudatelCall" 
        fkcolumn="CudatelCallID">

   <CFPROPERTY 
        name="WebRequestHistory" 
        type="array" 
        fieldtype="one-to-many" 
        cfc="WebRequestHistory" 
        singularname="WebRequestHistory" 
        orderBy="DateTime DESC"
        fkcolumn="WebRequestID">

    <cfproperty name="Note" type="string">
    <cfproperty name="DateTime" type="date">
    
    <cffunction name="mdToText" access="public" output="no" returntype="string">
        <cfif getPhysicianConsultation()>
            <cfreturn 'MD'>
        <cfelse>
            <cfreturn 'RN'>
        </cfif>
    </cffunction>

    <cffunction name="save" access="public" output="no" returntype="boolean">
        <cfset o_History = EntityNew("WebRequestHistory")>

        <cfset o_History.setWebRequestStatus(this.getWebRequestStatus())>
        <cfset o_History.setNote(this.getNote())> 
            
        <cfset o_History.setUser(EntityLoad("User", 28, true))> 
        <cfset o_History.setDateTime(Now())>
    
        <cfset EntitySave(this)>

        <cfset o_History.setWebRequestObj(this)>
        <cfset EntitySave(o_History)>

        <cfreturn true>
    </cffunction>
        
</cfcomponent>




<cfcomponent persistent="true" table="WebRequestHistory">

    <cfproperty name="id" fieldtype="id" column = "WebRequestHistoryID" generator="increment"> 

    <cfproperty
        name="WebRequestObj"
        fieldtype="many-to-one" 
        cfc="WebRequest"
        fkcolumn="WebRequestID"> 

    <cfproperty 
    name="WebRequestStatus" 
        fieldtype="many-to-one" 
        cfc="WebRequestStatus" 
        fkcolumn="WebRequestStatusID">

    <cfproperty name="Note" type="string" default="">

    <cfproperty 
    name="User" 
        fieldtype="many-to-one" 
        cfc="User" 
        fkcolumn="UserID">
        
    <cfproperty name="DateTime" type="date">
        
        
</cfcomponent>



FROM Application.cfc:

<CFSET this.ormenabled = "true"> 
<CFSET this.ormsettings.logSQL = "false">  
<CFSET this.ormSettings.dbCreate = "none" />
<CFSET this.scriptprotect="all">
<CFSET this.setClientCookies=false>
<CFSET THIS.ormsettings.cfclocation = "/xmdroot/model/beans">




--
You received this message because you are subscribed to the Google Groups "cf-orm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cf-orm-dev+...@googlegroups.com.
To post to this group, send email to cf-or...@googlegroups.com.
Visit this group at http://groups.google.com/group/cf-orm-dev.
For more options, visit https://groups.google.com/d/optout.

Puritan Paul

unread,
Mar 30, 2015, 2:38:02 PM3/30/15
to cf-or...@googlegroups.com
Yeah this is good info, thank you.  A few question, if you don’t mind:

Are there any important relationships between /approot/www/Application.cfc and /approot/appname/Application.cfc?  Anything needed to make sure hibernation sessions remain in sync with DB, etc?

Out of curiosity, how do you handle your environmental switches in the settings file?  We usually do it based off of the url, but I’m wondering if some local config file would really be better?

What are these pseudoconstructors for?

Regarding the transactions - that makes sense to me.  I assumed it would just be transactions wrapping higher level service functions as you describe.  I guess the only thing I’m not sure about is service functions that call other service functions that would likely be wrapped in a transaction already.  Is nesting a problem?

Thanks for the insights.




Cameron Childress

unread,
Mar 30, 2015, 3:14:56 PM3/30/15
to cf-or...@googlegroups.com
On Mon, Mar 30, 2015 at 2:37 PM, Puritan Paul wrote:
Are there any important relationships between /approot/www/Application.cfc and /approot/appname/Application.cfc?  

Not really. Just the shared model and configs. 
 
Anything needed to make sure hibernation sessions remain in sync with DB, etc?

Well, I suppose if I were using caching with ORM it would probably be a good idea to make sure they are both using the same cache. In this case I'm not. The transaction statements should make sure both apps can talk to the DB without crushing each other just like transactions in normal SQL does. 
 
Out of curiosity, how do you handle your environmental switches in the settings file?  We usually do it based off of the url, but I’m wondering if some local config file would really be better?

I use if statements that are largely based on a URL pattern. FW/1 also has some environment config options but I prefer to keep it all in a format that's outside the framework so I can use the include in other places if needed.

 
What are these pseudoconstructors for?

That's just all the "this scope" stuff in the Application.cfc.

Regarding the transactions - that makes sense to me.  I assumed it would just be transactions wrapping higher level service functions as you describe.  I guess the only thing I’m not sure about is service functions that call other service functions that would likely be wrapped in a transaction already.  Is nesting a problem?

I generally only do transactions at the highest level, which is a Controller in FW/1 and Endpoint in Taffy. It doesn't matter how much nesting there is inside, it's all captured by the top level Controller/Endpoint statement. As long as you aren't breaking the rules and calling ORM/SQL other places it's nice and tidy.

Also - If anyone else on the list sees problems with these methods I'd love to hear feedback as well.
 
-Cameron

Puritan Paul

unread,
Mar 30, 2015, 3:27:37 PM3/30/15
to cf-or...@googlegroups.com
Last curiosity question - what are your taffy endpoints?  Are they just a layer between the services and Taffy?  

I work in basically a two man group, so these architectural insights are nice to see.  I appreciate it.


Cameron Childress

unread,
Mar 30, 2015, 3:42:10 PM3/30/15
to cf-or...@googlegroups.com
On Mon, Mar 30, 2015 at 3:27 PM, Puritan Paul wrote:
Last curiosity question - what are your taffy endpoints?  Are they just a layer between the services and Taffy?  

I don't think you are asking what a Taffy endpoint is, since that's covered int he Taffy docs and examples.

Conceptually though - I see the Taffy endpoints as serving pretty much the same role as FW/1 Controllers do in a FW/1 App. They call services to do work, and manage the input/output of data in the REST API. The endpoints are the C in MVC.

The endpoints call the model through services. The services and model are the M in MVC.

There really isn't a "view" in Taffy since it's all output as JSON. Taffy handles that JSON "view" for you. so really JSON or XML output is the V in MVC here.

-Cameron

Puritan Paul

unread,
Mar 30, 2015, 4:04:12 PM3/30/15
to cf-or...@googlegroups.com
Right, I’m just unaccustomed to reading ‘endpoint’.   We’ve just got them all lumped in a resources folder.

Thanks again.  I’ll get back whenever I make headway on the Duplicate error.


Cameron Childress

unread,
Mar 30, 2015, 4:09:11 PM3/30/15
to cf-or...@googlegroups.com
Oh you are right, Taffy does call them resources. I started calling them Endpoints and never looked back. Same thing...

-Cameron

Puritan Paul

unread,
Apr 2, 2015, 3:10:36 PM4/2/15
to cf-or...@googlegroups.com
So you don’t name that application the same thing in /approot/www/Application.cfc  and  /approot/appname/Application.cfc?  I’m referring to THIS.name.  For that matter, do you correlate much of the THIS scope between the two?

Grasping for some straws chasing this Duplicate problem down.  It’s hoping around amongst objects lately - one day the duplicate is on one table, the next day another.

Oiy.



Cameron Childress

unread,
Apr 3, 2015, 8:40:53 AM4/3/15
to cf-or...@googlegroups.com
On Thu, Apr 2, 2015 at 3:10 PM, Puritan Paul wrote:
So you don’t name that application the same thing in /approot/www/Application.cfc  and  /approot/appname/Application.cfc?  I’m referring to THIS.name.  For that matter, do you correlate much of the THIS scope between the two?

No I name them differently because they are different applications. This means you cannot share session data or application data between the two, but I don't WANT to share that between the two. FW/1 and Taffy also both store certain information in the application scope and I think it would be potentially risky to try to make them share the same name.

 
Grasping for some straws chasing this Duplicate problem down.  It’s hoping around amongst objects lately - one day the duplicate is on one table, the next day another.

I guess that was your initial question and it wasn't ever answered. Most of the time when I see a duplicate key error it's because.

1) entitySave() being called twice on the same object.
2) You are setting the PK manually on something and accidentally making two objects have the same PK.

You could also have a cascade situation where you are saving a composite object and then also explicitly saving one of it's children separately. I expect hibernate should be able to figure that out but I feel like I'v run across situations where it didn't.

Also, you might turn on ORM's logging and see if that gives you more information.

this.ormSettings.logSQL = true;

The log will be in the CF logs folder with your application.log, etc. Just don't leave this on in production for too long since that log can get very large very quickly.
 
-Cameron

Puritan Paul

unread,
Apr 6, 2015, 2:38:00 PM4/6/15
to cf-or...@googlegroups.com
Finally got back to this today.

I made a very slim version of my application, and I can verify that it’s suffering the same duplication errors.  I’m going to continue trying to whittle it down, but here’s what I’ve got so far - in case something jumps out as a problem with my configuration:

—————

/Application.cfc

/model/services/newSvc.cfc
/model/beans/UserLogin.cfc
/model/legacy/oldSvc.cfc

/api/rest/Application.cfc
/api/rest/resources/authentication.cfc


—————

/Application.cfc

component {
    THIS.datasource = "xmdlocaldevdb";
    THIS.di1location = "./model";
THIS.mappings[ "/legacy" ] = ('./model/legacy');

THIS.ormenabled = "true";
THIS.ormsettings.cfclocation = "./model/beans";
THIS.ormsettings.logSQL = "true";
THIS.ormSettings.dbCreate = "none";

    function onApplicationStart() {
APPLICATION.beanFactory = new di1.ioc("#THIS.di1location#");

APPLICATION.OldSvc = createObject('component', 'model/legacy/oldSvc').init();
    }
}

—————

/api/rest/Application.cfc
component extends="taffy.core.api" {
    THIS.name = "XMD_DUPE_REST";
THIS.datasource = "xmdlocaldevdb";

THIS.mappings['/resources'] = expandPath('./resources');
THIS.ormenabled = "true";
 THIS.ormsettings.cfclocation = "/xmdtestroot/model/beans"; 
THIS.ormsettings.logSQL = "true";
THIS.ormSettings.dbCreate = "none";
    setting showdebugoutput="true";

// THIS.wschannels = [{name="test1"}];

    variables.framework = {
   reloadKey = "reload",
   reloadPassword = "true",
   reloadOnEveryRequest = false,
   allowCrossDomain = true
};

function onApplicationStart() {
   APPLICATION.beanFactory = new di1.ioc('/xmdtestroot/model');

   //set bean factory into Taffy
   VARIABLES.framework.beanFactory = APPLICATION.beanfactory;

   super.onApplicationStart();
}

    function onTaffyRequest(verb, cfc, requestArguments, mimeExt, headers) {
return true;
}
}

—————

/model/services/newSvc.cfc
<cfcomponent accessors="true">

    <cffunction name="init" access="public" output="no">
        <cfreturn this>
    </cffunction>

    <cffunction name="authenticateUser" access="public" output="no">
        <cfargument name="username" type="string" required="yes">
        <cfargument name="password" type="string" required="yes">

            <cfset LOCAL.userLogin = EntityNew("UserLogin")>
            < cfset LOCAL.userLogin.setUserID(41)>
            <cfset LOCAL.userLogin.setDateTime(Now())>
            <cfset EntitySave(LOCAL.userLogin)>        

        <cfreturn LOCAL.userLogin>
   </cffunction>
</cfcomponent>

—————

/model/legacy/oldSvc.cfc
<CFCOMPONENT>

    <CFFUNCTION name="init" access="public" returntype="oldSvc" output="no">
        <CFARGUMENT name="dsn" type="string" required="false">

        <CFRETURN this>
    </CFFUNCTION>

<CFFUNCTION name="loginUser" access="public" output="no">
    <CFARGUMENT name="userName" type="string" required="yes">
        <CFARGUMENT name="password" type="string" required="yes”>

            <CFSET LOCAL.userLogin = EntityNew("UserLogin")>
            <CFSET LOCAL.userLogin.setUserID(41)>
            <CFSET LOCAL.userLogin.setDateTime(Now())>
            <CFSET EntitySave(LOCAL.userLogin)>
            
            <CFRETURN LOCAL.userLogin> 
    </CFFUNCTION>
</CFCOMPONENT>

—————

/model/beans/UserLogin.cfc
<CFCOMPONENT persistent="true" table="UserLogins">
    <CFPROPERTY name="id" fieldtype="id" column="UserLoginID" generator="increment"> 
<CFPROPERTY name="DateTime" type="date">
<CFPROPERTY name="UserID" type="numeric">
</CFCOMPONENT>

—————
So not too much.  I have a test page in the main application (/index.cfm) that runs:
—————

<cfloop from="1" to="10" index="i">
<cfset login = APPLICATION.OldSvc.loginUser(userName = “TEST", password = “PASSWORD")>
</cfloop>


—————
And I have an angular test page that hits the taffy side 10 times.

I’ll then switch back and forth between environments.  Eg.  Run ten from main app, run 10 from angular, run 10 again from main app - an here is where I’ll see the error.  Looking at the hibernate log, I see that it’s not running a
    select
        max(UserLoginID) 
    from
        UserLogins

when I return to running the main app test.  Here’s the hibernate log:
—————


04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    select
        max(UserLoginID) 
    from
        UserLogins

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:12 [catalina-exec-3] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-1] HIBERNATE DEBUG - 
    select
        max(UserLoginID) 
    from
        UserLogins

04/06 11:16:24 [catalina-exec-1] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-9] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-10] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-2] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-11] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-12] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-9] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-6] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-2] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:24 [catalina-exec-1] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

??? SHOULD HAVE ANOTHER SELECT MAX HERE ???

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE DEBUG - 
    insert 
    into
        UserLogins
        (DateTime, UserID, UserLoginID) 
    values
        (?, ?, ?)

04/06 11:16:32 [catalina-exec-7] HIBERNATE ERROR - Duplicate entry '20' for key 'PRIMARY'

04/06 11:16:32 [catalina-exec-7] HIBERNATE ERROR - Could not synchronize database state with session

org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:179)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at coldfusion.orm.hibernate.SessionWrapper.flush(SessionWrapper.java:176)
at coldfusion.orm.hibernate.HibernateSessionManager.flushSession(HibernateSessionManager.java:217)
at coldfusion.orm.hibernate.HibernateSessionManager.flushAllCurrentSessions(HibernateSessionManager.java:271)
at coldfusion.orm.hibernate.HibernatePersistenceManager.onPageRequestEnd(HibernatePersistenceManager.java:1038)
at coldfusion.orm.hibernate.HibernatePersistenceManager$HibernateEventListener.onPageRequestEnd(HibernatePersistenceManager.java:1155)
at coldfusion.filter.ApplicationFilter.firePageRequestEnd(ApplicationFilter.java:610)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:475)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:112)
at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:30)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:94)
at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:79)
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.filter.CachingFilter.invoke(CachingFilter.java:62)
at coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:151)
at coldfusion.CfmServlet.service(CfmServlet.java:204)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:414)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Caused by: java.sql.BatchUpdateException: Duplicate entry '20' for key 'PRIMARY'
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1819)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1281)
at coldfusion.server.j2ee.sql.JRunStatement.executeBatch(JRunStatement.java:340)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 47 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '20' for key 'PRIMARY'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:389)
at com.mysql.jdbc.Util.getInstance(Util.java:372)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:973)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3835)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3771)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2535)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1911)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2145)
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1777)
... 51 more
 



I’m not totally sure what more to pare down, but I’ll keep looking.  Thanks again for the help, and let me know if I can do something else to provide more info.




Cameron Childress

unread,
Apr 6, 2015, 6:24:58 PM4/6/15
to cf-or...@googlegroups.com
On Mon, Apr 6, 2015 at 2:37 PM, Puritan Paul wrote:
<CFCOMPONENT persistent="true" table="UserLogins">
    <CFPROPERTY name="id" fieldtype="id" column="UserLoginID" generator="increment"> 


  • increment: This algorithm generates identifiers of type longshort, or int by incrementing a counter maintained by ORM. This is commonly used when auto-generation for the primary key is not enabled in the table and you want ORM to generate the primary key. This should be used when a single instance of ColdFusion is the only process to insert data into the table.


This definition is a little sketchy to me. Especially when you are allowing CF to manage your ORM session and flush it. sounds like hibernate is maintaining your PK and attempting to increment it on your behalf. This is something I'd do explicitly yourself or allow the DB to do it for you. Allowing ORM to manage is would be my last choice.

If you want to let the DB manage it, I'd try a generator like identity, sequence, or native.

I use generator="uuid" if I want it generated by ORM. But most often I assign it myself as a UUID string and use the assigned generator. This allows N systems to work separately (aka: mobile offline) and be synchronized later. 

-Cameron 

Brian Kotek

unread,
Apr 6, 2015, 7:49:36 PM4/6/15
to cf-or...@googlegroups.com
1) Always use a transaction when inserting/updating anything.
2) Let the database manage the PK. If for some reason this is impossible, use a UUID.

Puritan Paul

unread,
Apr 6, 2015, 8:07:14 PM4/6/15
to cf-or...@googlegroups.com
Ah, that looks promising!  Especially that last sentence about a single CF instance.  I’ll try one of the others now.  Thanks again!


Puritan Paul

unread,
Apr 8, 2015, 7:36:40 PM4/8/15
to cf-or...@googlegroups.com
Looks like that did the trick!  Thanks again for the help, and great catch!


Puritan Paul

unread,
Apr 10, 2015, 5:51:59 PM4/10/15
to cf-or...@googlegroups.com
I’m trying to implement my environment includes in a fashion similar to yours - and I’m hitting a wall.  I’m sure I’m overlooking something simple.  If you can spare a sec…

Application.cfc

component {
  include "config/environmentSettings.cfm";

  function onApplicationStart() {
    include "config/app/applicationStart.cfm";
  }
}

config/environmentSettings.cfm:

<script>
    THIS.di1location = "/xmdroot/model";
</script>

config/app/applicationStart.cfm:

<cfset APPLICATION.beanFactory = new di1.ioc("#THIS.di1location#")>


And I’m getting
Element DI1LOCATION is undefined in THIS.

Am I doing something wrong here?




Cameron Childress

unread,
Apr 12, 2015, 5:58:36 PM4/12/15
to cf-or...@googlegroups.com
On Fri, Apr 10, 2015 at 5:51 PM, Puritan Paul wrote:
config/environmentSettings.cfm:

<script>
    THIS.di1location = "/xmdroot/model";
</script>

I'd use request scope for your environment settings and only use Application.cfc's "this" scope for actual documented Application.cfc settings used by CF - nothing else.

-Cameron
 
Reply all
Reply to author
Forward
0 new messages