Find the next tag inside a dictionary - sql-server

I have an XML field inside a SQL Server table, on which I need to know if a couple key/value with a given key and a given value is already used in my table.
So here is my table (simplified).
dbo.mytable :
primaryKey, INT
xml_data, NOT NULL
And the xml_data field is caracterized with the following XSN :
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xsd:element name="a">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:sequence>
<xsd:element name="b" type="NonEmptyString" />
<xsd:element name="c" type="NonEmptyString" />
<xsd:element name="d" type="NonEmptyString" />
<xsd:element name="e" type="xsd:dateTime" />
<xsd:element name="dict">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:choice maxOccurs="unbounded">
<xsd:sequence>
<xsd:element name="key" type="NonEmptyString" />
<xsd:element name="value" type="xsd:string" />
</xsd:sequence>
</xsd:choice>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="version" type="xsd:float" />
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="NonEmptyString">
<xsd:restriction base="xsd:string">
<xsd:minLength value="1" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
For this given XML (for example) :
<a>
<b>Value</b>
<c>Value</c>
<d>Value</d>
<e>2017-02-14T00:00:00</e>
<dict>
<key>myKey</key>
<value>myValue</value>
<key>anotherKey</key>
<value>myValue</value>
</dict>
</a>
I need to know if the table contains for the first key "myKey" the value "myValue".
I think I can use the [xml_data].exist() function, but I have issues about how my XQuery should be formed.
I started writing the following XQuery :
for $key in /a/dict/key where data($key) = ''myKey'' return $key
But I can't find out, how to get the following tag.
Which could give "hypotethically" something like :
SELECT [xml_data].exist('
for $key
in /a/dict/key
where data($key) = ''myKey''
return $key.followingTag == ''myValue''
') FROM dbo.mytable;
References :
https://msdn.microsoft.com/en-us/library/ms189869.aspx

Considering the following answer : https://stackoverflow.com/a/19253986/3635715
And the following documentation : https://msdn.microsoft.com/en-us/library/ms178030.aspx
Here is the XQuery for my problem :
data(/a/dict/value[. >> (/a/dict/key[. = "myKey"])[1]])[1]
Here is the answer for my problem :
SELECT COUNT(primaryKey) FROM dbo.mytable
WHERE [xml_data].value('
data(/a/dict/value[. >> (/a/dict/key[. = "myKey"])[1]])[1]
', 'varchar(max)') = 'myValue'
Be careful this answer only works for first key corresponding to "myKey" found.
Which for me will be the case.
Also considering this Answer : https://stackoverflow.com/a/10408858/3635715
The query can be parameterised this way :
DECLARE #key AS NVARCHAR(max)
DECLARE #value AS NVARCHAR(max)
SET #key = N'myKey'
SET #value = N'myValue'
SELECT COUNT(primaryKey) FROM dbo.mytable
WHERE [xml_data].value('
data(/a/dict/value[. >> (/a/dict/key[. = sql:variable("#key")])[1]])[1]', 'varchar(max)
') = #value

Related

How do I form an Amazon FBA CartonContentsRequest XML with more than one SKU per carton

I am using the SubmitFeed _POST_FBA_INBOUND_CARTON_CONTENTS_ from Amazon's Feeds Api. I submit this XML doc. I have used this call successfully for simple cases where there is just one SKU per carton. This shipment I want to have three SKUs per carton. The order in sellercentral shows all the correct dimension and weight data but has it as three cartons, not one, even though I submitted only one carton id.
<?xml version="1.0" encoding="UTF-8"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>**************</MerchantIdentifier>
</Header>
<MessageType>CartonContentsRequest</MessageType>
<Message>
<MessageID>1</MessageID>
<CartonContentsRequest>
<ShipmentId>FBA******S2F</ShipmentId>
<NumCartons>1</NumCartons>
<Carton>
<CartonId>55172</CartonId>
<Item>
<SKU>SKU-ABC</SKU>
<QuantityShipped>48</QuantityShipped>
<QuantityInCase>24</QuantityInCase>
</Item>
<Item>
<SKU>SKU-DEF</SKU>
<QuantityShipped>48</QuantityShipped>
<QuantityInCase>24</QuantityInCase>
</Item>
<Item>
<SKU>SKU-XYZ</SKU>
<QuantityShipped>72</QuantityShipped>
<QuantityInCase>24</QuantityInCase>
</Item>
</Carton>
</CartonContentsRequest>
</Message>
</AmazonEnvelope>
The XSD file is here
https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_4_1/CartonContentsRequest.xsd
<?xml version="1.0"?>
<!-- Revision="$Revision: #3 $" -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!--
$Date: 2006/11/21 $
AMAZON.COM CONFIDENTIAL. This document and the information contained in it are
confidential and proprietary information of Amazon.com and may not be reproduced,
distributed or used, in whole or in part, for any purpose other than as necessary
to list products for sale on the www.amazon.com web site pursuant to an agreement
with Amazon.com.
-->
<xsd:include schemaLocation="amzn-base.xsd"/>
<xsd:element name="CartonContentsRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ShipmentId">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="FBA[A-Z0-9]+" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="NumCartons" type="xsd:positiveInteger" />
<xsd:element name="Carton" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CartonId">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="[a-zA-Z0-9]+" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="Item" maxOccurs="200">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="SKU"/>
<xsd:element name="QuantityShipped" type="xsd:positiveInteger" />
<xsd:element name="QuantityInCase" type="xsd:positiveInteger" default="1"/>
<xsd:element name="ExpirationDate" type="xsd:date" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
It turns out my problem was elsewhere so you can safely assume the XML I posted here is valid.

XSD for two complex types

I am using File adapter (SOA 11.1.1.1.7) to read the content of a file and the file looks like this
a|b|c|d|e
a|b|c|d|e
a|b|c|d|e
a|b|c|d|e
a|b|c|d|e
Total no of rows 5
For reading this , I need to create a xsd.My problem lies in the last line (
Total no of rows 5). Guys could you please help me in creating the xsd.My current xsd looks like this..which is not working. Please help
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"
xmlns:tns="http://TargetNamespace.com/File_Outbound_Ref"
targetNamespace="http://TargetNamespace.com/File_Outbound_Ref"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
nxsd:version="NXSD"
nxsd:stream="chars"
nxsd:encoding="US-ASCII"
nxsd:hasHeader="true"
nxsd:headerLines="1"
nxsd:headerLinesTerminatedBy="${eol}"
>
<xsd:element name="Root-Element">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Data_Details" type="tns:DataReport" nxsd:style="array" />
<xsd:element name="Trailor_Details" type="tns:Trailor_Record" nxsd:style="array" nxsd:cellSeparatedBy="${eol}" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="DataReport">
<xsd:sequence>
<xsd:element name="a" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="|" nxsd:quotedBy=""" />
<xsd:element name="b" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="|" nxsd:quotedBy=""" />
<xsd:element name="c" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="|" nxsd:quotedBy=""" />
<xsd:element name="d" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="|" nxsd:quotedBy=""" />
<xsd:element name="e" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" nxsd:quotedBy=""" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Trailor_Record"> <xsd:sequence>
<xsd:element name="Row_Count" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" />
</xsd:sequence>
</xsd:complexType>
In Read file action, under "Configure Operation" we have "Remove Trailer" option and enable it and mention the number of row. So in your case you need one last row to remove so mention 1.

Apex type not found for element : userDetails

I m getting the following response from the webservice
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><GetUserResponse xmlns="urn:wwservice"><userDetails xmlns="">Successfully write a web service hurray</userDetails></GetUserResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
But I getting Apex type not found for element : userDetails
Here's my wsdl file
<?xml version="1.0" encoding="ISO-8859-1"?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:wwservice" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:wwservice">
<types>
<xsd:schema elementFormDefault="qualified" targetNamespace="urn:wwservice">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/"/>
<xsd:complexType name="GetUserRequestType">
<xsd:all>
<xsd:element name="Username" type="xsd:string" form="unqualified"/>
<xsd:element name="Password" type="xsd:string" form="unqualified"/>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="GetUserResponseType">
<xsd:all>
<xsd:element name="userDetails" type="xsd:string" form="unqualified"/>
</xsd:all>
</xsd:complexType>
<xsd:element name="GetUser" type="tns:GetUserRequestType"/>
<xsd:element name="GetUserResponse" type="tns:GetUserResponseType"/>
</xsd:schema>
</types>
<message name="GetUserRequest">
<part name="parameters" element="tns:GetUser"/></message>
<message name="GetUserResponse">
<part name="parameters" element="tns:GetUserResponse"/></message>
<portType name="PsocialPortType">
<operation name="GetUser">
<input message="tns:GetUserRequest"/>
<output message="tns:GetUserResponse"/>
</operation>
</portType>
<binding name="PsocialBinding" type="tns:PsocialPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetUser">
<soap:operation soapAction="urn:wwservice#GetUser" style="document"/>
<input><soap:body use="literal" namespace="urn:wwservice"/></input>
<output><soap:body use="literal" namespace="urn:wwservice"/></output>
</operation>
</binding>
<service name="Psocial">
<port name="PsocialPort" binding="tns:PsocialBinding">
<soap:address location="http://example.com/webservice/wwservice.php"/>
</port>
</service>
</definitions>
Please let me know where i getting wrong
I m using this to create WSDL
$server = new soap_server();
// Changed for coupons data start
$server->soap_defencoding = 'UTF-8';
$server->decode_utf8 = false;
// Changed for coupons data end
//$server->configureWSDL('m-way', 'urn:wwservice');
$server->configureWSDL('Psocial', 'urn:wwservice',false,'document');
// New function for spiff
$server->register("GetUser",
array('Username'=>'xsd:string','Password'=>'xsd:string'),
array('userDetails'=>'xsd:string'),
'urn:wwservice',
'urn:wwservice#GetUser', 'document', 'literal'
);
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA)? $HTTP_RAW_POST_DATA : file_get_contents('php://input');
$server->service($HTTP_RAW_POST_DATA);
The problem is that the SOAP response you get doesn't match the description of it in the WSDL, the WSDL has elementFormDefault="qualified" for the schema, which says that child element would be in the namespace, e.g. its saying the response should be
<GetUserResponse xmlns="urn:wwservice">
<userDetails>Hello</userDetails>
</GetUserResponse>
but the actual response you get has
<GetUserResponse xmlns="urn:wwservice">
<userDetails xmlns="">Successfully write a web service hurray</userDetails>
</GetUserResponse>
Note how the namespace for the userDetails element is different. You should either update the WSDL to say elementForDefault="unqualified" or update the web service to return the correct namespace on the userDetails element.

Example of XSD for a simple table to load into SQL Server using XML Bulk Load

I am trying to get a relatively simple xml file to load into SQL Server 2008 as a table using bulk load. My primary issue is crafting a XSD that works with bulk load. Here is my current XSD. The table I am looking to create will only have nvarchar fields and datetime fields.
I know I have errors in how I put together the XSD. Now the XSD is working but bulk load is not loading any data.
I am really looking for an example of a XSD and XML file that can be successfully loaded into SQL Server using Bulk Load. That allows me to specify the max length and data type. The XML will include some non standard characters so I have used for that data.
Below are a sample of my XSD and XML. Thanks.
<?xml version="1.0" ?>
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd"/>
<xsd:element name="FWO2-2011-03-03T22-53-47" sql:relation="XMLTESTTBL2">
<xsd:complexType>
<xsd:attribute name="fIld" type="sqltypes:int" use="required"/>
<xsd:attribute name="o">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="255"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="n">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="255"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="f">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="255"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="s" type="sqltypes:int"/>
<xsd:attribute name="a" type="sqltypes:int"/>
<xsd:attribute name="l" type="sqltypes:datetime"/>
<xsd:attribute name="d" type="sqltypes:datetime"/>
<xsd:attribute name="e">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="255"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="b" type="sqltypes:datetime"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<?xml version="1.0" ?>
<dataroot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FWO2-2011-03-03T22-53-47.xsd" generated="2008-05-08T16:37:19">
<FWO2-2011-03-03T22-53-47>
<n><![CDATA[2007 Protiviti Pricing Tool.zip]]></n>
<s>3073536</s>
<f><![CDATA[C:\Users\ethkin01\Desktop\Desktop\2011-02-06]]></f>
<a>32</a>
<l>1/28/2011 3:27:43 PM</l>
<d>1/12/2011 12:09:31 PM</d>
<e><![CDATA[.zip]]></e>
<b>1/12/2011 12:09:31 PM</b>
</FWO2-2011-03-03T22-53-47>
<FWO2-2011-03-03T22-53-47>
<n><![CDATA[2010 Updated 1-11-11.xlsm]]></n>
<s>1149607</s>
<f><![CDATA[C:\Users\ethkin01\Desktop\Desktop\2011-02-06]]></f>
<a>32</a>
<l>1/11/2011 4:59:46 PM</l>
<d>1/11/2011 4:59:45 PM</d>
<e><![CDATA[.xlsm]]></e>
<b>1/11/2011 4:59:45 PM</b>
</FWO2-2011-03-03T22-53-47>
</dataroot>
try xsd2db at www.sourceforge.net

NHibernate and sql timestamp columns as version

I've been racking my head trying to get Nhibernate to work with a byte
array as version mapping to an sql timestamp. I'd implemented an
IUserVersionType but Nhibernate was creating varbinary in the database
rather than timestamp. Inspired by a blog post by Ayende recently on
concurrency, I changed my mapping to specify the sql-type to timestamp
which worked perfectly. However I now face a rather curious problem
wherein Nhibernate does an insert, gets the new version and then
immediately tries to do an update and attempts to set the version
column, which being an sql timestamp fails.
This is my mapping:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Core.Domain, Version=0.1.3397.31993, Culture=neutral,
PublicKeyToken=94dc7dc697cfcfc0" namespace="Core.Domain.Entities"
default-lazy="false">
<class name="Contact" table="Contacts" xmlns="urn:nhibernate-
mapping-2.2" optimistic-lock="version" dynamic-insert="true" dynamic-
update="true">
<id name="Id" type="Int32" column="Id">
<generator class="identity" />
</id>
<version name="Version" type="BinaryBlob" generated="always"
unsaved-value="null">
<column name="Version" sql-type="timestamp" not-null="false" />
</version>
<property name="Title" type="String">
<column name="Title" length="5" />
</property>
<property name="FirstName" type="String">
<column name="FirstName" not-null="true" length="50" />
</property>
<property name="MiddleName" type="String">
<column name="MiddleName" length="50" />
</property>
<property name="LastName" type="String">
<column name="LastName" not-null="true" length="50" />
</property>
<property name="Suffix" type="String">
<column name="Suffix" length="5" />
</property>
<property name="Email" type="String">
<column name="Email" length="50" />
</property>
<bag name="PhoneNumbers" inverse="true" cascade="all-delete-
orphan">
<key foreign-key="FK_Contacts_PhoneNumbers_ContactId" on-
delete="cascade" column="ContactId" />
<one-to-many class="Core.Domain.Entities.PhoneNumber,
Core.Domain, Version=0.1.3397.31993, Culture=neutral,
PublicKeyToken=94dc7dc697cfcfc0" />
</bag>
<property name="DateCreated" type="DateTime">
<column name="DateCreated" />
</property>
<property name="DateModified" type="DateTime">
<column name="DateModified" />
</property>
<property name="LastModifiedBy" type="String">
<column name="LastModifiedBy" />
</property>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Core.Domain, Version=0.1.3397.31993, Culture=neutral,
PublicKeyToken=94dc7dc697cfcfc0" namespace="Core.Domain.Entities"
default-lazy="false">
<class name="Customer" table="Customers" xmlns="urn:nhibernate-
mapping-2.2" optimistic-lock="version" dynamic-insert="true" dynamic-
update="true">
<id name="Id" type="Int32" column="Id">
<generator class="identity" />
</id>
<version name="Version" type="BinaryBlob" generated="always"
unsaved-value="null">
<column name="Version" sql-type="timestamp" not-null="false" />
</version>
<property name="AccountNumber" access="nosetter.pascalcase-
underscore" type="String">
<column name="AccountNumber" unique="true" length="25" />
</property>
<!-- other mappings... -->
<property name="DateCreated" type="DateTime">
<column name="DateCreated" />
</property>
<property name="DateModified" type="DateTime">
<column name="DateModified" />
</property>
<property name="LastModifiedBy" type="String">
<column name="LastModifiedBy" />
</property>
<joined-subclass name="Core.Domain.Entities.Individual,
Core.Domain, Version=0.1.3397.31993, Culture=neutral,
PublicKeyToken=94dc7dc697cfcfc0" table="Individuals">
<key column="CustomerId" />
<many-to-one fetch="join" lazy="false" not-null="true"
cascade="all" unique="true" not-found="exception" name="Contact"
column="ContactID" />
<bag name="Addresses" table="Addresses_Individuals">
<key column="AddressId" foreign-
key="FK_Addresses_Individuals_Addresses_AddressId" />
<many-to-many column="IndividualId"
class="Core.Domain.Entities.Address, Core.Domain,
Version=0.1.3397.31993, Culture=neutral,
PublicKeyToken=94dc7dc697cfcfc0" foreign-
key="FK_Addresses_Individuals_Individuals_IndividualId" />
</bag>
</joined-subclass>
<joined-subclass name="Core.Domain.Entities.Store, Core.Domain,
Version=0.1.3397.31993, Culture=neutral,
PublicKeyToken=94dc7dc697cfcfc0" table="Stores">
<key column="CustomerId" />
<many-to-one unique="true" cascade="save-update" fetch="join"
not-null="true" not-found="exception" name="Address"
column="AddressId" />
<many-to-one lazy="proxy" not-null="true" cascade="all" not-
found="exception" name="Client" column="ClientId" />
<property name="StoreName" type="String">
<column name="StoreName" not-null="true" length="50" />
</property>
<bag name="Contacts" table="Contacts_Stores">
<key column="ContactId" foreign-
key="FK_Contacts_Stores_Contacts_ContactId" />
<many-to-many column="StoreId"
class="Core.Domain.Entities.Contact, Core.Domain,
Version=0.1.3397.31993, Culture=neutral,
PublicKeyToken=94dc7dc697cfcfc0" foreign-
key="FK_Contacts_Stores_Stores_StoreId" />
</bag>
</joined-subclass>
</class>
</hibernate-mapping>
Calling Session.Save on an Individual with associated Contact results
in the following error:
NHibernate: INSERT INTO Addresses (Line1, PostalCode, Country,
DateCreated, DateModified, LastModifiedBy) VALUES (#p0, #p1, #p2, #p3,
#p4, #p5); select SCOPE_IDENTITY(); #p0 = 'Order Address Line 1', #p1
= 'CV31 6BW', #p2 = 'United Kingdom', #p3 = '20/04/2009 19:45:32', #p4
= '20/04/2009 19:45:32', #p5 = ''
NHibernate: SELECT address_.Version as Version22_ FROM Addresses
address_ WHERE address_.Id=#p0; #p0 = '1'
NHibernate: INSERT INTO Contacts (FirstName, LastName, DateCreated,
DateModified, LastModifiedBy) VALUES (#p0, #p1, #p2, #p3, #p4); select
SCOPE_IDENTITY(); #p0 = 'Joe', #p1 = 'Bloggs', #p2 = '20/04/2009
19:45:34', #p3 = '20/04/2009 19:45:34', #p4 = ''
NHibernate: SELECT contact_.Version as Version33_ FROM Contacts
contact_ WHERE contact_.Id=#p0; #p0 = '1'
NHibernate: INSERT INTO Customers (AccountNumber, DateCreated,
DateModified, LastModifiedBy) VALUES (#p0, #p1, #p2, #p3); select
SCOPE_IDENTITY(); #p0 = '', #p1 = '20/04/2009 19:45:34', #p2 =
'20/04/2009 19:45:34', #p3 = ''
NHibernate: INSERT INTO Individuals (ContactID, CustomerId) VALUES
(#p0, #p1); #p0 = '1', #p1 = '1'
NHibernate: SELECT individual_1_.Version as Version2_ FROM Individuals
individual_ inner join Customers individual_1_ on
individual_.CustomerId=individual_1_.Id WHERE
individual_.CustomerId=#p0; #p0 = '1'
NHibernate: UPDATE Contacts SET Version = #p0 WHERE Id = #p1 AND
Version = #p2; #p0 = 'System.Byte[]', #p1 = '1', #p2 = 'System.Byte[]'
System.Data.SqlClient.SqlException: Cannot update a timestamp column.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception,
Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException
exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning
(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,
SqlCommand cmdHandler, SqlDataReader dataStream,
BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject
stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader
ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds
(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean
returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior
cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String
method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery
(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
in c:\CSharp\NH\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs:
line 203
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object
id, Object[] fields, Object[] oldFields, Object rowId, Boolean[]
includeProperty, Int32 j, Object oldVersion, Object obj,
SqlCommandInfo sql, ISessionImplementor session) in c:\CSharp\NH
\nhibernate\src\NHibernate\Persister\Entity
\AbstractEntityPersister.cs: line 2713
NHibernate.Exceptions.GenericADOException: could not update:
[Core.Domain.Entities.Contact#1][SQL: UPDATE Contacts SET Version =
#p0 WHERE Id = #p1 AND Version = #p2]
Any ideas why NHibernate is attempting to update the version column
for Contact, even though it didn't for the Address?
I have found that using dynamic-insert="true" on the class along with causes this issue. I use the following mapping successfully:
...
<class name="Contact" table="Contact">
<id name="ID" column="ID" type="int">
<generator class="identity" />
</id>
<version name="Version" generated="always" unsaved-value="null" type="BinaryBlob"/>
...
The Address doesn't have a version column I assume.
I wonder where you have the sql-type from. Why not this way?
<version name="Version" type="Timestamp" generated="always" unsaved-value="null">
<column name="Version" not-null="false" />
</version>
You need of course a DateTime in the entity.
http://ayende.com/Blog/archive/2009/04/15/nhibernate-mapping-concurrency.aspx

Resources