How does one access analytical views using odata? - hana

I have an analytical view and an .xsodata to expose it to web. The question is how is the access url formed? HANA documentation is insufficient here, and the same for the moderated SCN.
Here is my func_x_cview.xsodata:
service namespace "CTag" {
"MyPackage::FUNC_X_CALC_VIEW" as "CView" keys generate local "ID"
parameters via entity "InputParams" ;
}
http://awshana:8000/package/path/to/xsodata/file/$metadata shows:
<EntityType Name="InputParamsType">
<Key>
<PropertyRef Name="ATTRIBUTE"/>
<PropertyRef Name="ATTRIBUTE_VALUE"/>
<PropertyRef Name="category"/>
<PropertyRef Name="from_date"/>
<PropertyRef Name="process"/>
<PropertyRef Name="to_date"/>
</Key>
<Property Name="ATTRIBUTE" Type="Edm.String" Nullable="false" MaxLength="50"/>
<Property Name="ATTRIBUTE_VALUE" Type="Edm.String" Nullable="false" MaxLength="100"/>
<Property Name="category" Type="Edm.String" Nullable="false" MaxLength="50"/>
<Property Name="from_date" Type="Edm.DateTime" Nullable="false"/>
<Property Name="process" Type="Edm.String" Nullable="false" MaxLength="50"/>
<Property Name="to_date" Type="Edm.DateTime" Nullable="false"/>
<NavigationProperty Name="Results" Relationship="CTag.InputParams_CViewType"
FromRole="InputParamsPrincipal"
ToRole="CViewDependent"/>
</EntityType>
What should be the access url? Does the xsodata need any tweaking?
Thanks
--EDIT--
When trying url like suggested by ongis-nade to http://awshana:8000/Pkg/Proj_X/services/tagA.xsodata/InputParams%28%27category%27=%27abcd%27%29/Results?$select=exception_name then I get an error like the following:
<error>
<code/>
<message xml:lang="en-US">
No property ''category'' exists in type 'CTag.InputParamsType'.
</message>
</error>
This is confusing as we can see a property named category in the entity named InputParamsType in the $metadata query.
Removing the single quotes around category (also tried double-quoting) gives
http://awshana:8000/Pkg/Proj_X/services/tagA.xsodata/InputParams%28category=%27abcd%27%29/Results?$select=exception_name
<error>
<code/>
<message xml:lang="en-US">
The number of keys specified in the URI at position 27 does not match number of key properties for the resource 'CTag.InputParamsType'.
</message>
</error>
So a single quote is needed.
A step closer but still the same question. Do I need to qualify each parameter name somehow?
Thanks.

I believe the URL will be formed as:
http://awshana:8000/Pkg/Proj_X/services/tagA.xsodata/InputParams(category='abcd')/Results?
The "InputParams" name is of course reflected in your service definition
I also found a good example here: http://scn.sap.com/community/developer-center/hana/blog/2013/01/22/rest-your-models-on-sap-hana-xs

May be a bit late: But you have to specify a value for each key parameter.
Note also, that timestamps must be specified in ODatas Edm.DateTime format.
Example for your service:
http://server:8080/pathToService/tagA.xsodata/InputParams(ATTRIBUTE='?',ATTRIBUTE_VALUE='?',category='?',from_date=datetime'2014-01-01T00:00:00',process='?',to_date=datetime'2014-09-01T00:00:00')/Results

Related

Wrong value while using property mediator in WSO2 ESB

I have made a proxy service where the value of "Request1" property showing properly as in incoming request
<s1:PALMUpdateCatalogueRequest xmlns:s1="http://www.example.org/prodcatItemWSO2/">
<s1:updateproductCatalogueList>
<s1:catalogueinternalid>1</s1:catalogueinternalid>
ABC
<s1:itemList>
<s1:Item>
<s1:custitem_prod_cat_item>390</s1:custitem_prod_cat_item>
<s1:item_price_level>7</s1:item_price_level>
<s1:typeofitem>PQR</s1:typeofitem>
</s1:Item>
</s1:itemList>
</s1:updateproductCatalogueList>
<s1:transactionid />
</s1:PALMUpdateCatalogueRequest>
But,after calling a sequence when I am using this below expression to fetch the value of Request1,it's not showing.
What will I do to solve this issue?
<property name="REQUEST" expression="get-property('Request1')" scope="default" type="STRING"/>
You should use correct scopes to read properties. If your property is in the synapse scope, you can read it like this.
<property name="REQUEST" expression="$ctx:Request1" scope="default" type="STRING"/>

NHibernate with Second Level Cache Not Rehydrating Properties Marked insert="false" update="false"?

Having trouble with implementing second level cache in Nhibernate. I have a class mapped as follows:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Data" namespace="Data">
<class name="Account" table="Accounts" lazy="false">
<cache region="Standard" usage="read-write" include="all"/>
<id column="ID" name="ID">
<generator class="assigned" />
</id>
<version name="VersionStamp" column="VersionStamp" type="integer" unsaved-value="0" />
<property name="Name" not-null="true" />
<property name="Type" not-null="true" />
<property name="ClientID" not-null="true" insert="false" update="false" />
<property name="DateCreated" not-null="true" type="UtcDateTime" />
<property name="LastUpdatedDate" not-null="true" type="UtcDateTime" />
<property name="IsActive" not-null="true" />
<many-to-one name="Client" class="Client" column="ClientID" not-found="exception" not-null="true" />
</class>
</hibernate-mapping>
The property "ClientID" is a foreign key into the Clients table and the Client many-to-one property uses it to look up the associated client object.
When I add a new Account, I look up the Client object from the database with a Session.Get and assign it to my Account object's Client property. Behind the scenes, this also automatically populates the ClientID property when the object is written to the database, and the ID is correctly stored in the database. When I retrieve the Account object from the database by ID using Session.Get, all the fields are populated correctly when the object is retrieved.
However, when I implement the second level cache using the settings shown above, the ClientID property is NOT populated when the Account object is retrieved using Session.Get, but the Client property is populated correctly. Is there some reason why this will not work with second level cache? Or have I done something wrong in my mapping/configuration?
For now I am just using SysCache as my caching provider, and both query and second level cache are turned on. The Client class mapping contains a corresponding one-to-many property for the Accounts.
I like the convenience of having the ClientID property on my Account class, so that I can read it without using the Client property, and it seems to work fine without caching.
Thanks for any help.
Rich
I tried to reproduce your situation locally. With your mapping (used the same as the snippet above) I was able to get incorrect behaviour only on UPDATE. In that case, the ClientID was cached, and while the Client reference was changed, the ClientID remained unchanged. In other cases caching was working as expected.
The solution is to change the mapping. The below suggested mapping is the most suitable for read-only properties like ClientID. (I am using that approach as well).
<property name="ClientID" formula="[ClientId]"
not-null="true" insert="false" update="false" />
So the trick is in the formula mapping instead of Column (the default when none is provided)

NHibernate - Trying to get it to use a SQL Server Row version

As per the StackOverflow question 'NHibernate and sql timestamp columns as version', I use the following mapping:
<version name="RowNumber" generated="always" unsaved-value="null" type="BinaryBlob">
<column name="RowNumber" not-null="false" sql-type="timestamp" />
</version>
<property name="CreateDate" column="CreateDate" type="DateTime" update="false" insert="false" />
(Other properties after this last).
But when I run my ASP.MVC app I get:
[Path]\Clients.hbm.xml(7,90): XML validation error: The element 'urn:nhibernate-mapping-2.2:version' cannot contain child element 'urn:nhibernate-mapping-2.2:column' because the parent element's content model is empty.
But as far as I can see 2.2 is the latest version of the mapping, so how can anyone put a column element inside the version element?
Sorry if this is really basic,
In case anyone else has this problem:
It works as Ayende Rahien specifies in this blog on NHibernate - but only (AFAIK) on version 2.1.n; I was using 2.0.n. I also think you need the object's field/property to be byte[], not System.Linq.Binary as that type has no default constructor (but I am not sure about this - I seemed to have to do this)
Example (excuse the names):
<version name="RowKludge" type="BinaryBlob" generated="always" unsaved-value="null" >
<column name="RowNumber"
not-null="false"
sql-type="timestamp"/>
</version>
A SQL server 'timestamp' is not your regular timestamp, hence the requirement that the type should be a binary blob.
Note that if you do migrate you will need to change the NHibernate configuration in Web/App config - most tutorials currently available seem to be for v.2.0 (or earlier) - you need an uptodate reference or tutorial for 2.1
A quick look in the documentation reveals that your mapping is not correct. It should be something like this:
<version name="RowNumber" column="RowNumber"
generated="always" unsaved-value="null"
type="Timestamp" />
Best Regards,
Oliver Hanappi

Inheritance: Criterion on entity type and sub class properties

I have a inheritance hierarchy which I have mapped in NHibernate using Table-per-class. My mappping file looks like the one below (lots of properties omitted).
To query this hierarchy, I am building a dynamic DetachedCriteria for Message based on filter input from the user. Messages (of any type in the hierarchy) should be returned to the user in one list.
I would like to build a criteria based on the type of message, ie. the user could specify to get all messages of type SMSMessage or EmailMessage with a ReceivedDate > '2009-01-01'. How would I go about to do that?
In the same query, the user could specify that if the Message is an InternalMessage, it should have Priority = 2. How would I specify such type-specific predicates?
All this is possible to do in LINQ, so I am hoping I can do it in NHibernate as well.
<class name="Message" table="Message" abstract="true" discriminator-value="null">
<id name="MessageId">
<generator class="identity" />
</id>
<discriminator column="Type" type="byte" />
<property name="ParentId" />
<property name="ReceivedDate" />
...
<subclass name="SMSMessage" discriminator-value="0">
<property name="Text" column="Text" />
...
</subclass>
<subclass name="MMSMessage" discriminator-value="1">
<property name="Subject" />
...
</subclass>
<subclass name="EmailMessage" discriminator-value="2">
<property name="BodyPlainText" />
...
</subclass>
<subclass name="InternalMessage" discriminator-value="4">
<property name="Priority" />
...
</subclass>
</class>
I kind of figured this out myself, but in the end I ended up reverting to pure SQL since I hit too many roadblocks with HQL/Criterias. Anyways, I can share how I did this.
Maybe not pretty, but I solved it by adding the discriminator column as a regular property to the top level class in the hierarchy (Message) and employed restrictions against that column.
It turns out that you can specify restrictions against properties for subclasses even in the top-level query, so this was easier than I thought. It was just a matter of specifying the restrictions.

Mapping multiple Values to a Value Object in NHibernate

i'm fairly new to NHibernate and although I'm finding tons of infos on NHibernate mapping on the web, I am too silly to find this piece of information.
So the problem is, i've got the following Model:
this is how I'd like it to look. One clean person that has two Address Properties.
In the database I'd like to persist this in one table.
So the Person row would have a ShippingStreetname and a Streetname Column, the one mapped to ShippingAddress.Streetname and the other to Address.StreetName
I found an article on fluent interfaces, but still haven't figured out how to do this through the XML Configuration.
Thanks in advance!
Update: I found the solution to this by myself. This can be done through the node and works rather straightforward.
To achieve the mapping of Address and ShippingAddress I just had to add the following to the
<component name="Address" class="Address">
<property name="Streetname"></property>
<property name="Zip"></property>
<property name="City"></property>
<property name="Country"></property>
</component>
<component name="ShippingAddress" class="Address">
<property name="Streetname" column="ShippingStreetname" />
<property name="Zip" column="ShippingZip" />
<property name="City" column="ShippingCity" />
<property name="Country" column="ShippingCountry" />
</component>
Ok. I found the solution myself.
The key is the construct in the XML configuration and it works rather nicely.
Here is how it's done:
<component name="Address" class="Address">
<property name="Streetname"></property>
<property name="Zip"></property>
<property name="City"></property>
<property name="Country"></property>
</component>
<component name="ShippingAddress" class="Address">
<property name="Streetname" column="ShippingStreetname" />
<property name="Zip" column="ShippingZip" />
<property name="City" column="ShippingCity" />
<property name="Country" column="ShippingCountry" />
</component>
you could configure this as two relations. e.g.
<many-to-one name="ShippingAddress" class="Yournamespace.Address"/>
<many-to-one name="Address" class="Yournamespace.Address"/>
You dont even need an Id for an address. Just think how expensive is to maintain an Id. You have concurrency problems, you need uniqueness, and so on. This is the aim of the ValueObjects (do not get confused with System.ValueObject see DDD definition for ValueObject). In this case Address is a ValueObject so it does not required an Id. And if you need a collection of Address you map it like a "" see http://www.nhforge.org/doc/nh/en/index.html#collections-ofvalues.