Hi all,
I am having problems using Transfer with the jTDS JDBC Driver (1.2.2)
and CF8 (update 8.0.1) and MS SQL Server 2005.
It is not possible to insert a new record into the database via the
framework. The error I get is the following:
You have attempted to dereference a scalar variable of type class
java.lang.String as a structure with members.
The error occurred in C:\Inetpub\wwwroot\transfer\com\sql
\TransferInserter.cfc: line 162
Called from C:\Inetpub\wwwroot\transfer\com\sql\TransferInserter.cfc:
line 66
Called from C:\Inetpub\wwwroot\transfer\com\sql\transaction
\Transaction.cfc: line 210
Called from C:\Inetpub\wwwroot\transfer\com\sql\transaction
\Transaction.cfc: line 89
Called from C:\Inetpub\wwwroot\transfer\com\sql\TransferInserter.cfc:
line 50
Called from C:\Inetpub\wwwroot\transfer\com\sql\SQLManager.cfc: line
62
Called from C:\Inetpub\wwwroot\transfer\com\Transfer.cfc: line 183
Called from C:\Inetpub\wwwroot\transfer\com\Transfer.cfc: line 166
Called from C:\Inetpub\wwwroot\TestProject\index.cfm: line 16
160 : else
161 : {
162 : invokeSetPrimaryKey(arguments.transfer,
qAfterInsertTransfer.id);
163 : }
164 : }
The problem is related to the auto-generated keys feature which might
be handled in a different way by the JDBC drivers. I have no problems
if switching to the default driver shipped with CF (I think it's the
one from DataDirect)
If you want to reproduce the problem:
1. Download jTDS from
http://jtds.sourceforge.net/
2. Extract the jar file from the zip and copy it into <CF_HOME>\lib
3. Restart CF
4. Create Datasource in CF Admin using the following parameters
(select "other" from driver dropdown list)
JDBC URL: jdbc:jtds:<server_type>://<server>[:<port>][/<database>]
[;<property>=<value>[;...]]
(example: jdbc:jtds:sqlserver://
127.0.0.1/TestProject)
Driver Class: net.sourceforge.jtds.jdbc.Driver
Driver Name: JTDS
add username and password.
5. use Transfer with the created datasource and try to insert a new
row
I do not know if there is a parameter to use in the JDBC URL or any
jTDS property to let the driver behave in another way. Any hints on
that are really welcome.
To "manually" reproduce the problem (without using transfer), you can
do the following:
<cfquery name="insertTest" result="insertTestResult"
datasource="TestProjectJTDS">
INSERT INTO Test (
bla
)
VALUES (
'test'
)
SELECT SCOPE_IDENTITY() AS ID
</cfquery>
<cfdump var="#insertTest#" />
<cfdump var="#insertTestResult#" />
This will work with the DataDirect JDBC driver and will produce an
error in jTDS (insertTest is undefined).
A possible workaround could be to do the following:
<cfquery name="insertTest" result="insertTestResult"
datasource="TestProject">
INSERT INTO Test (
bla
)
VALUES (
'test'
)
SELECT SCOPE_IDENTITY() AS ID
</cfquery>
<cfif structKeyExists(insertTestResult, "id")>
<!--- use the id provided by cf in the result structure --->
<cfdump var="#insertTestResult#" />
<cfset newID = insertTestResult.id />
<cfelse>
<!--- use the manually added id from scope_identity --->
<cfdump var="#insertTest#" />
<cfset newID = insertTest.id />
</cfif>
But this is not available in Transfer. So I recommend to add such kind
of logic (or maybe another - better - solution), to support other JDBC
drivers within the framework.
Any comments are appreciated.
Cheers,
Jan