I have some XML snippets that I store via NHibernate (3.2.0.4000) in a SQL Server database. The table column is defined as XML. Storing and Updating of the XML is working, but in the database I am missing the first node with the encoding and version information.
C# object, inner XML:
<?xml version="1.0" encoding="utf-16"?>
<RsSn>
<Layermapping xmlns="someNamespace">
<Layer layerName="0" layerDescription="5876548" />
<Layer layerName="1" layerDescription="5876549" />
</Layermapping>
</RsSn>
SQL Server Profiler when the data is inserted:
declare #p6 xml
set #p6=convert(xml,
N'<RsSn><Layermapping xmlns="someNamespace">
<Layer layerName="0" layerDescription="5876548"/>
<Layer layerName="1" layerDescription="5876549"/>
</Layermapping>
</RsSn>'
)
The <?xml version="1.0" encoding="utf-16"?> element is missing!
Content of SQL server column (via SSMS studio):
<RsSn>
<Layermapping xmlns="someNamespace">
<Layer layerName="0" layerDescription="5876548" />
<Layer layerName="1" layerDescription="5876549" />
</Layermapping>
</RsSn>
NHibernate Configuration (part of mapping file)
<class name="SnippetEntity" table="tblSnippet">
<id name="SnippetPK" column="SnippetPK" type="Int64">
<generator class="native" />
</id>
<property name="ResourceData" column="ResourceData" type="NHibernate.Type.XmlDocType"/>
</class>
I am not allowed to update the NHibernate assembly.
Is this the correct type that I am using in the mapping file?
Is there some other configuration I have to use so the document is stored "well formed" in the database?
The top <?xml version="1.0" encoding="utf-16"?> construct is called XML prolog. It is not mandatory to have it. XML is well-formed without it.
SQL Server stores XML as Unicode (utf-16). There is no other encoding. That's why SQL Server strips the prolog when it exists in XML.
Related
I have the following XML document
<?xml version="1.0" encoding="utf-8"?>
<GovTalkMessage xmlns="http://www.govtalk.gov.uk/CM/envelope">
<EnvelopeVersion>2.0</EnvelopeVersion>
<Header>
<MessageDetails>
<Class>
</Class>
<Qualifier>request</Qualifier>
<Function>submit</Function>
<CorrelationID />
<Transformation>
</Transformation>
<GatewayTest>0</GatewayTest>
</MessageDetails>
<SenderDetails>
<IDAuthentication>
<SenderID>
</SenderID>
<Authentication>
<Method>clear</Method>
<Role>principal</Role>
<Value></Value>
</Authentication>
</IDAuthentication>
</SenderDetails>
</Header>
<GovTalkDetails>
<Keys>
<Key Type="TaxOfficeNumber">
</Key>
<Key Type="TaxOfficeReference">
</Key>
</Keys>
<TargetDetails>
<Organisation>IR</Organisation>
</TargetDetails>
<ChannelRouting>
<Channel>
<URI>
</URI>
<Product></Product>
<Version>
</Version>
</Channel>
<timestamp>
</timestamp>
</ChannelRouting>
</GovTalkDetails>
<Body>
<IRenvelope xmlns="">
<IRheader>
<Keys>
<Key Type="TaxOfficeNumber">
</Key>
<Key Type="TaxOfficeReference">
</Key>
</Keys>
<PeriodEnd>
</PeriodEnd>
<DefaultCurrency>GBP</DefaultCurrency>
<IRmark>
</IRmark>
<Sender>Employer</Sender>
</IRheader>
</IRenvelope>
</Body>
</GovTalkMessage>
and I'm loading it into a XMLDocument using the XMLDocument.load().
Now when I run xpath queries against it they are not responding as I would expect and I cant seem to find out why, I have used XPath Visualiser tool and it shows that for example //Keys/Key should return 4 nodes
When I run the following c#
document.SelectNodes(#"//Keys/Key") it returns 2 nodes not the expected 4.
Also when I run the following
document.SelectNodes(#"//Header") it returns 0 nodes
Also running
document.SelectNodes(#"GovTalkMessage") returns 0 nodes.
All suggestions and help greatfully received.
Thanks
Ben
XPath needs namespaces. The tags you are trying to select are in one, so you have to tell the select where to look.
I'm having an issue where I'm sending a message to nServiceBus with a message data field of variable length. nServiceBus is using nHibernate to create a table called
[NServiceBus].[PendingMentorEmailSagaData]
from a class called PendingMentorEmailSagaData . The message field is however getting set to nvarchar(255), I am looking for a way to have it set to nvarchar(MAX).
I've tried using an embedded hbm file, but am getting a "persistent class PendingMentorEmailSagaData not found" error.
This probably means I can't figure out what class to set the file too.
The hbm file:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="PendingMentorEmailSagaData">
<id name="Id" />
<property name="OriginalMessageId" />
<property name="Originator" />
<property name="PendingMentorEmailCommandId" />
<property name="JobBoardCode" />
</class>
</hibernate-mapping>
PendingMentorEmailSagaData is the name of the saga's data class.
Create a PendingMentorEmailSagaData.hbm.xml file in the same project that the saga exists on, eg:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.2">
<class name="MY_NAMESPACE.PendingMentorEmailSagaData, MY_ASSEMBLY_NAME" table="PendingMentorEmailSagaData" dynamic-update="true" optimistic-lock="all">
<id name="Id" type="Guid">
<generator class="assigned" />
</id>
<property name="Originator" />
<property name="OriginalMessageId" />
<property name="LargeText" type="StringClob" />
</class>
</hibernate-mapping>
2. Mark that file as an Embedded Resource
Goal:
Make the stored procedure to be working with nhibernate.
Problem:
I retrieve an error message:
could not execute query
[ exec sp_retrieveAllProductList #p0 ]
Name:Produkt_kategori - Value:Dryck
[SQL: exec sp_retrieveAllProductList #p0]
What is the problem in the source code?
Info:
- Using VS 2013.
For AliasToBean to work, the returned column names (and their types) must match exactly the properties on the class to convert to.
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="data_layer" namespace="data_layer">
<sql-query name="sp_retrieveAllProductList">
<return-scalar column="Produkt" type="string" />
<return-scalar column="Produkt_kategori" type="string" />
exec sp_retrieveAllProductList :Produkt_kategori
</sql-query>
</hibernate-mapping>
Never forget to change the column to the right value.
Here is a part of my xml file
<teams>
<team-profile>
<name>Australia</name>
<id>1</id>
<stats type="Test">
<span>1877-2010</span>
<matches>721</matches>
<won>339</won>
<lost>186</lost>
<tied>2</tied>
<draw>194</draw>
<percentage>47.01</percentage>
</stats>
<squad>
<player id="135" fullname="Shane Warne"/>
<player id="136" fullname="Damien Martyn"/>
<player id="138" fullname="Michael Clarke"/>
</squad>
</team-profile>
</team>
I have read somewhere that there is a way to save this XML directly to database. I am using VS2010. I have created the dataset, for the data i need from this xml. Is there any way to map this XML directly on dataset?
Any other idea?
I also have to save some other more complex XML files to database.
I have tried xsd.exe to create xsd schema for this XML.
SQL Server 2005+ has a native XML datatype, if you create a column, you can simply do an insert into that column, here is an insert similar to yours, this table's second column's datatype is xml
INSERT INTO docs VALUES (1, '<book genre="security"
publicationdate="2002" ISBN="0-7356-1588-2">
<title>Writing Secure Code</title>
<author>
<first-name>Michael</first-name>
<last-name>Howard</last-name>
</author>
<author>
<first-name>David</first-name>
<last-name>LeBlanc</last-name>
</author>
<price>39.99</price>
</book>')
INSERT INTO docs VALUES (2,
'<doc id="123">
<sections>
<section num="1"><title>XML Schema</title></section>
<section num="3"><title>Benefits</title></section>
<section num="4"><title>Features</title></section>
</sections>
</doc>')
I'm trying to solve pretty easy problem. I want to establish connection to 2 totally different databases ( but both mysql ). Now I tried to solve this by creating multiple config files and then creating multiple sessions. Everything works until I reached relations.
I have 2 tables in 2 databases:
db1
- News
db2
- News_Authors
I added News to db1 config and News_Authors to db2 config. When I try to build simple one-to-one relation error, I receive:
An association from the table songs refers to an unmapped class: db1.News_Authors
News.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="project.News, project" table="news" lazy="false">
<id name="id" column="id" type="integer" length="11">
<generator class="native" />
</id>
<property name="title" type="String" length="255" />
<property name="authorid" type="integer" length="5" />
<one-to-one name="NewsAuthor" cascade="all-delete-orphan" lazy="proxy" column="authorid" unique="true" />
</class>
</hibernate-mapping>
News_Authors.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="project.News_Authors, project" table="news_authors" lazy="false">
<id name="id" column="id" type="integer" length="11">
<generator class="native" />
</id>
<property name="name" type="String" length="255" />
</class>
</hibernate-mapping>
config
I added this to enable mappings. Now If I set both in one config files, everything works...
<mapping resource="project.News.hbm.xml" assembly="project" />
So how could I during creating of session also "notify" nhibernate that I have multiple sessions? Or should I pick totally another approach?
One other possible solution would be to create views in one of the sql server databases to reference the tables in the other. Views map just like tables and its easy to do a view that returns something like:
select * from db2.News_Authors
in the db1 database.
this way you would only need a single .hbm.xml file that maps to one of the two databases.
Hope this helps,
-Max
What you are after is not multiple sessions but multiple session factories. See this for more details.
The key here is that you don't have to initialize your session factory through config file - you can do it programatically. And it's just a step to have two session factories.