Mapping JAXBelement in Mule Data mapper - mule

I have a generated SOAP response from a wsdl for one Web Service. This is how one of the elements looks like in the wsld definition:
<xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/>
In the POJO, it looks like this :
#XmlElementRef(name = "Name", namespace = "http://schemas.datacontract.org/2004/07/Web.WebServices", type = JAXBElement.class, required = false)
protected JAXBElement<String> name;
When trying to set the value, in the Data Mapper, I see the following:
The problem is that I am not allowed to just drag and drop the "name" value.
How should I map the name value from the JSON on the left to the name value?

You will have to drag input.name to the value field of name name/value.
Script view should look something like:
output.value = input.name;

Related

WCF Desrialization of date with offset

I am facing an issue where wcf response contains datetime stamp as
1978-05-20T11:12:00+2:00
I want to retrieve the response as the same like 1978-05-20T11:12:00.
Please note, this offset (+02:00 in the above example) value might change for different response. So value might be
1978-05-20T11:12:00+2:00
1978-05-20T11:12:00+5:00
1978-05-20T11:12:00+6:00
Here is what I did to fix this...
update the wsdl file from
<xs:element name="start" type="xs:date"/>
to
<xs:element name="start" type="xs:string"/>
and generated the proxy.. now the returned value with using this proxy was like 1978-05-20T11:12:00+2:00 in start field. they I used string function to extract just the desired part.
Alternatively, proxy file can be updated from
[XmlAttribute( type = "Date", ElementName = "start" )]
public DateTime start {
..
}
to
[XmlAttribute( type = "string", ElementName = "start" )]
public string start {
...
}

spyne generating invalid schema

I am trying to use spyne from master branch as the released versions are not compatible with python3 and I have models defined like these:
class currency(ComplexModel):
data = XmlData(Decimal)
class mntCurrency(currency):
code = XmlAttribute(String)
class CreditLmt(ComplexModel):
curr = mntCurrency
I have plugged these models into a simple HelloWorld Service which returns CreditLmt in response. But when I try to run my soap server, spyne complains with the following:
lxml.etree.XMLSchemaParseError: Element
'{http://www.w3.org/2001/XMLSchema}extension': The content is not
valid. Expected is (annotation?, ((group | all | choice | sequence)?,
((attribute | attributeGroup)*, anyAttribute?)))., line 16
Which is correct because spyne generates the following xsd:
<xs:complexType name="mntCurrency">
<xs:complexContent>
<xs:extension base="tns:currency">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="code" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
<xs:sequence>
<xs:element name="test" type="xs:token" minOccurs="0" nillable="true"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
I am using XmlData because I want to have reponse such that it looks like this:
<tns:currency code="826">10.0</tns:currency>
So how do I define my models?
An example for generating this element:
<tns:currency code="826">10.0</tns:currency>
... is as follows:
from spyne import *
from spyne.util.xml import get_object_as_xml
from lxml import etree
class Currency(ComplexModel):
value = XmlData(Decimal)
code = XmlAttribute(Integer32(values=[826, 234, 555]))
class SomeObject(ComplexModel):
handle = Unicode
currency = Currency
obj = SomeObject(handle="aaaa", currency=Currency(value=D('123.45'), code=555))
elt = get_object_as_xml(obj)
print(etree.tostring(elt, pretty_print=True))
As for the error, it is coming directly from libxml. It is essentially saying that the Xml Schema standard doesn't allow lone XmlData entries in a ComplexModel subclass. If you think this is an error, you must complain to the Xml Schema working group.

Search for multiple values in an xml column

Environment: SQL Server 2012. Primary and secondary (value) index is built on xml column.
Say I have a table Message with xml column WordIndex. I also have a table Word which has WordId and WordText. Xml for Message.WordIndex has the following schema:
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com">
<xs:element name="wi">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="w">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="p" type="xs:unsignedByte" />
</xs:sequence>
<xs:attribute name="wid" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
and some data to go with it:
<wi xmlns="http://www.example.com">
<w wid="1">
<p>28</p>
<p>72</p>
<p>125</p>
</w>
<w wid="4">
<p>89</p>
</w>
<w wid="5">
<p>11</p>
</w>
</wi>
I need to search for multiple values in my xml column WordIndex either using OR or AND. What I'm doing is fairly rudimentary, since I'm a n00b in XQuery (taken from debug output, hence real values):
with xmlnamespaces(default 'http://www.example.com')
select
m.Subject,
m.MessageId,
m.WordIndex.query('
let $dummy := 0
return
<word_list>
{
for $w in /wi/w
where $w/#wid=64
return <word wid="64" pos="{data($w/p)}"/>
}
{
for $w in /wi/w
where $w/#wid=70
return <word wid="70" pos="{data($w/p)}"/>
}
{
for $w in /wi/w
where $w/#wid=63
return <word wid="63" pos="{data($w/p)}"/>
}
</word_list>
') as WordPosition
from
Message as m
-- more joins go here ...
where
-- more conditions go here ...
and m.WordIndex.exist('/wi/w[#wid=64]') = 1
and m.WordIndex.exist('/wi/w[#wid=70]') = 1
and m.WordIndex.exist('/wi/w[#wid=63]') = 1
How can this be optimized?
Not sure I understand what your expected results are, but you could make this a bit more generic and data-driven (eg using sql:column or sql:variable). Try something like this:
declare #wids table ( wid INT PRIMARY KEY )
insert into #wids ( wid )
values ( 64 ), ( 70 )
;with xmlnamespaces(default 'http://www.example.com')
select
m.Subject,
m.MessageId,
m.WordIndex.query('
return
<word_list>
{
for $w in /wi/w
where $w/#wid = sql:column("w.wid")
return <word wid="{$w/#wid}" pos="{data($w/p)}"/>
}
</word_list>
') as WordPosition
from
Message as m
cross apply #wids w
where m.WordIndex.exist('wi/w[#wid=sql:column("w.wid")]') = 1

coldfusion ORM: many-to-many conditional property

I am trying to add a where clause to a many-to-many property I have defined in one of my objects. I must be doing something wrong though because I keep getting hibernate errors saying that the column doesn't exist.
in the template cfc:
<cfproperty
name="Settings"
fieldtype="many-to-many"
cfc="Setting"
linktable="settings_templates"
fkcolumn="templateID"
inversejoincolumn="settingsId"
where="deleted='false'"
>
In the settings cfc:
<cfproperty
name="templates"
fieldtype="many-to-many"
cfc="Template"
linktable="settings_templates"
fkcolumn="settingsId"
inversejoincolumn="templateID"
where="deleted='false'"
>
The error I am getting is:
08/02 16:06:27 [jrpp-170] HIBERNATE ERROR - [Macromedia][SQLServer
JDBC Driver][SQLServer]Invalid column name 'deleted'.
Can anyone see what I am doing wrong? there is a deleted column in both tables, but not in the link table.
The where property behavior for many-to-many is very strange...
In order to debug this, activate the Hibernate logging is primordial.
Refer you to this post: http://www.rupeshk.org/blog/index.php/2009/07/coldfusion-orm-how-to-log-sql/
Take this example:
Article.cfc
/**
* #output false
* #persistent true
* #table article
*/
component {
property name="id" fieldtype="id";
property name="title";
property
name="tags" singularname="tag"
fieldtype="many-to-many" cfc="Tag" linktable="link_article_tag" fkcolumn="articleId"
inversejoincolumn="tagId" where=" deleted = 0 "
;
}
Tag.cfc
/**
* #output false
* #persistent true
* #table tag
*/
component {
property name="id" fieldtype="id";
property name="name";
property name="deleted" dbdefault="0";
property
name="articles" singularname="article"
fieldtype="many-to-many" cfc="Article" linktable="link_article_tag" fkcolumn="tagId"
inversejoincolumn="articleId"
;
}
When I try to list all articles like this ormExecuteQuery('from Article'), see what is appened in the hibernate logs:
select
tags0_.articleId as articleId6_1_,
tags0_.tagId as tagId1_,
tag1_.id as id0_0_,
tag1_.name as name0_0_,
tag1_.deleted as deleted0_0_
from
link_article_tag tags0_
inner join
tag tag1_
on tags0_.tagId=tag1_.id
where
tags0_.deleted = 0
Damned! WTF :| tags0_ == join table ... You see what's wrong?
In order to understand this behavior, I'm going to activate HBMXML generation in Application.cfc with this.ormSettings.saveMapping = true
Here is the files:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class entity-name="Tag" lazy="true"
name="cfc:www.app.models.test.Tag" table="tag">
<id name="id" type="string">
<column length="255" name="id"/>
</id>
<property name="name" type="string">
<column name="name"/>
</property>
<property name="deleted" type="string">
<column default="0" name="deleted"/>
</property>
<bag name="articles" table="link_article_tag">
<key column="tagId"/>
<many-to-many class="cfc:www.app.models.test.Article" column="articleId"/>
</bag>
</class>
</hibernate-mapping>
What we can see: The where attribute is set at the bag level, not at the to many-to-many. If I edit like this:
<bag name="tags" table="link_article_tag">
<key column="articleId"/>
<many-to-many class="cfc:www.app.models.test.Tag" column="tagId" where=" deleted = 0 "/>
</bag>
The generated SQL become:
select
tags0_.articleId as articleId62_1_,
tags0_.tagId as tagId1_,
tag1_.id as id59_0_,
tag1_.name as name59_0_,
tag1_.deleted as deleted59_0_
from
link_article_tag tags0_
inner join
tag tag1_
on tags0_.tagId=tag1_.id
where
tag1_.deleted = 0
This method works but is not good for code maintenance and readability.
If anyone has a better solution, I'm interested.
So far, the only way around this that I have found is to override the getter using ORMExecuteQuery(). There I can query the objects directly and look for things such as this. Personally, I prefer to work in cfscript, so my code would look something like this:
public array function getSettings() {
return ORMExecuteQuery("SELECT s FROM template t JOIN t.settings s WHERE t.id=:id AND s.deleted=:deleted", {
deleted=false, id=this.getId()
});
}
N.B. – EXAMPLE NOT TESTED
Of course, you don't have to use the parameters as I have, you could just use deleted=false, but that's up to you (I like using parameters, personally).
Also, don't forget the singularName attribute on many-to-many properties.
On a related note, I've had issues using properties on both objects. You really only need to use them on the template object, in this case. Think about it this way: A template needs to know its settings, but the settings don't need to know about the template they belong to – using properties on both objects in this way can lead to errors, in some cases.

HiLo NHibernate id generator implementation

I would like to use "hilo" generator but there is no any complete example how to create "specific" table as NH documentation says, and which values pass to it.
The following code fragments taken from NH tutorial
public class Cat
{
private Int64 id;
private string name;
private char sex;
private float weight;
public Cat()
{}
public virtual Int64 Id
{
get { return id; }
set { id = value; }
}
....
}
Mapper
<hibernate-mapping ...>
<class name="Cat" table="Cat">
<id name="Id" >
<column name="CatId" sql-type="Int64" not-null="true"/>
<generator class="hilo"/>
</id>
<property name="Name">
<column name="Name" length="16" not-null="true" />
</property>
....
</class>
</hibernate-mapping>
DB table "Cat"
CatId bigint NOT NULL
Name varchar(16) NOT NULL
Sex char(1) NULL
Weight real NULL
doesn't create anything in the database by default.
Parameters in the "id" node
<param name="table">hi_value</param>
<param name="column">next_value</param>
<param name="max_lo">100</param>
gives "Invalid object name 'hi_value'" error message, without them I'm getting "Invalid object name 'hibernate_unique_key'."
Cuid.Comb that is shown in their tutorial works good but gives 99.12% of fragmentation when I added in a loop 20K cat objects.
Can somebody point me to an example of "hilo" implementation or give a tip what I'm missing?
Thanks.
This solution solved my problem. It's fairly simple, don't know why on nhibernate site there is no tiny example like that.
You may be running into NH-2687.