I have Odata service which exposes "StartAction" service operation. This operation returns ActionResponse entity
<EntityType Name="ActionResponse">
<Key>
<PropertyRef Name="FolderId" />
</Key>
<Property Name="FolderId" Type="Edm.String" Nullable="false" />
<Property Name="ClientData" Type="Edm.String" Nullable="true" />
<Property Name="ProcessCaption" Type="Edm.String" Nullable="true" />
<Property Name="ProcessName" Type="Edm.String" Nullable="true" />
<Property Name="ProjectName" Type="Edm.String" Nullable="true" />
<Property Name="ProjectVersion" Type="Edm.Int32" Nullable="false" />
<Property Name="ServerData" Type="Edm.String" Nullable="true" />
<Property Name="StageName" Type="Edm.String" Nullable="true" />
<Property Name="UserName" Type="Edm.String" Nullable="true" />
<NavigationProperty Name="Action" Relationship="Metastorm.EngineData.ActionResponse_Action_Action_ActionResponse" FromRole="ActionResponse_Action" ToRole="Action_ActionResponse" />
</EntityType>
<Association Name="ActionResponse_Action_Action_ActionResponse">
<End Role="ActionResponse_Action" Type="Metastorm.EngineData.ActionResponse" Multiplicity="0..1" />
<End Role="Action_ActionResponse" Type="Metastorm.EngineData.Action" Multiplicity="0..1" />
</Association>
when i try to $expand Action navigation property, i get the following error:
Query options $expand, $filter, $orderby, $inlinecount, $skip and $top cannot be applied to the requested resource
I can work it around if i will return IQueryable with only one item, but is looks ugly. Does anyone know any other way how to make $expand work for Service Operations which return a single entity?
Thanks in advance
P.S. The service have custom implementation
The service operation must return IQueryable in order for any of the other query options to work (this is necessary, since WCF DS needs the IQueryable to construct the expression for the additional query options).
It is perfectly fine to return an IQueryable with a single result in it. Add the [SingleResult] attribute on the service operation method to let WCF DS know that the IQueryable is only gonna return a single value (and so that the query options behave accordingly).
Related
I am creating a spring based web application that uses embedded hsqldb.
My spring config is pretty simple:
<jdbc:embedded-database id="dataSource" type="HSQL" >
<jdbc:script location="classpath:scripts/create-table-if-not-exists" />
</jdbc:embedded-database>
But with this config all data is stored in memory. Here is the data source url that is created
jdbc:hsqldb:mem:dataSource
I need to persist data to a file. So that I can use it again after server restart.
This solution worked for me
<bean class="org.apache.commons.dbcp2.BasicDataSource" id="dataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:#{systemProperties['user.home']}/db/data" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:scripts/create-table-if-not-exists" />
</jdbc:initialize-database>
I'm using a mapping with a filter.
But when I try to persist my object, it first wants to get a snapshot (because my Id is a string).
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="DomainLayer.General" assembly="DomainLayer">
<class name="Fund" table="OPENA_BriefW" lazy="false">
<id name="Id" column="`BRWNUMMER`" type="string" >
</id>
<property name="Name" column="`BRWNAAM`" type="string" />
<property name="Contact" column="`BRWNAAM2`" type="string" />
<property name="Address" column="`BRWADRES`" type="string" />
<property name="City" column="`BRWSTAD`" type="string" />
<property name="Zip" column="`BRWPOST`" type="string" />
<property name="Phone" column="`BRWTELEFOON`" type="string" />
<property name="Fax" column="`BRWTELEFAX`" type="string" />
<property name="Iban" column="`brw_iban`" type="string" />
<property name="BankAccount" column="`BRWBANKNU`" type="string" />
<property name="Swift" column="`brw_swift`" type="string" />
<property name="ReceiveOffice" column="`BRWONTVKANT`" type="int" />
<property name="RegionDirection" column="`BRWGEWESTDIR`" type="int" />
<many-to-one name="Country" class="DomainLayer.General.CodeDescription" fetch="join" not-found="ignore">
<formula>'ALG'</formula>
<formula>'0'</formula>
<formula>'WG030'</formula>
<column name="`BRWLAND`" />
<formula>:LanguageFilter.Id</formula>
</many-to-one>
</class>
</hibernate-mapping>
As you can see the filter :LanguageFilter.Id is the one causing the troubles. When I do a normal .List() it doesn't cause problems.
But when I persist, it first wants to check if the Fund already exists yes/no. By doing a .Get (with the Id).
Then I get the error can't retrieve snapshot because in my query he doesn't replace :LangaugeFilter.Id with the effective value i set on my session.
I enable the filter on my session like so:
session.EnableFilter("LanguageFilter").SetParameter("Id", 1);
Here's the filter-def mapping:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<filter-def name='LanguageFilter' >
<filter-param name='Id' type='System.Int32' />
</filter-def>
</hibernate-mapping>
This post (comment 4) http://ayende.com/blog/3993/nhibernate-filters says that session.Get and Load ignores filters.
Are there any alternatives, because I need that language to be variable.
Ok, what I did was the following: I didn't use SaveOrPersist, but Save when new and Persist when I had an old one. This didn't execute the extra get.
I am searching for a solution, to use Spring (V1.3.2) and NHibernate (V3.2.0) together with the declarative transactionmanagement of Spring to communicate with two independent SQLite database instances.
Currently I can read and write from/to both database instances but the transaction management only works for one database (DbProvider_DB1).
The „why“ is clear for me, but how can I use the declarative transaction management for both databases? Do I need two transaction manager? If yes, how can I define a second one and use it?
Here is my configuration, nothing strange but for the sake of completeness:
dao.xml
<tx:attribute-driven />
<!-- Datenbankprovider -->
<db:provider id="DbProvider_DB1" provider="SQLite-1.0.72" connectionString="Data Source=db1.db3;Version=3;New=False;" />
<db:provider id="DbProvider_DB2" provider="SQLite-1.0.72" connectionString="Data Source=db2.db3;Version=3;New=False;" />
<!-- SessionFactories -->
<object id="SessionFactory" abstract="true" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate32">
<property name="HibernateProperties">
<dictionary>...</dictionary>
</property>
<property name="ExposeTransactionAwareSessionFactory" value="true" />
</object>
<object id="SessionFactory_DB1" parent="SessionFactory" >
<property name="DbProvider" ref="DbProvider_DB1" />
</object>
<object id="SessionFactory_DB2" parent="SessionFactory" >
<property name="DbProvider" ref="DbProvider_DB2" />
</object>
<!-- Transactionmanager -->
<object id="transactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate32">
<property name="DbProvider" ref="DbProvider_DB1"/>
<property name="SessionFactory" ref="SessionFactory_DB1"/>
<property name="TransactionSynchronization" value="Always"/>
</object>
<!-- Data Access Objects -->
<object id="Dao_DB1" type="Dao1, Dao">
<property name="SessionFactory" ref="SessionFactory_DB1" />
</object>
<object id="Dao_DB2" type="Dao2, Dao">
<property name="SessionFactory" ref="SessionFactory_DB2" />
</object>
Dao
[Transaction]
public TEntity Save( TEntity entity )
{
CurrentSession.Save( entity );
return entity;
}
Thanx
The solution is to use the TxScopeTransactionManager instaed of HibernateTransactionManager.
<object id="transactionManager" type="Spring.Data.Core.TxScopeTransactionManager, Spring.Data">
<property name="TransactionSynchronization" value="Always"/>
</object>
<property name="Registration" column="vrn" type="String" length="16" />
<property name="Vin" column="vin" type="String" length="32" />
<property name="EngineCapacity" column="engineCapacityCC" type="Int32" />
<property name="Make" column="make" type="String" length="128" />
<property name="ModelDescription" column="modelDescription" type="String" length="128" />
<property name="ModelCode" column="modelCode" type="String" length="128" />**
<property name="RegistrationDate" column="registrationDate" type="DateTime" />
<property name="Manufacturer" column="manufacturer" type="String" length="128" />
<property name="ManufactureDate" column="manufactureDate" type="DateTime" />
<property name="Range" column="range" type="String" length="128" />**
<property name="DriveType" column="driveType" type="String" length="1" />
<property name="BodyType" column="bodyType" type="String" length="25" />
<property name="EngineType" column="engineType" type="String" length="25" />
<property name="Colour" column="colour" type="String" length="25" />
<property name="IsImported" column="IsImported" type="Boolean" />
<property name="IsLeftHandDrive" column="IsLeftHandDrive" type="Boolean" />
<property name="Range" column="ClientRangeCode" type="String" />**
<property name="ModelCode" column="ClientModelCode" type="String" />**
<property name="IsTaxi" column="IsTaxi" type="Boolean" />
This mapping raise and exception (duplicate property ......)
I need to map ModelCode to both ClientModelCode and modelCode columns
I need to do the same for the property Range
thanks
You can't. It's not possible, nor does it make sense, to have the same property name defined more than once in a class. Your class should have separate properties for ModelCode and ClientModelCode.
Another option is to have private members for ModelCode and ClientModelCode and expose just one through a public ModelCode property.
I'm rejigging our deploy scripts, and have moved to external config files for each defined environment. I have the ${environment} and the ${system} component passed as variables on the command line.
I load config.${environment}.xml, which contains a bunch of property definitions.
<property name="server.component1" value="server01" />
<property name="server.component2" value="server02" />
<property name="drive.component1" value="C:\" />
<property name="drive.component2" value="D:\" />
<property name="unc.component1" value="\\${server.component1}\Builds\${system}\${build.date}" />
<property name="unc.component2" value="\\${server.component2}\Builds\${system}\${build.date}" />
To determine the server to deploy to, I need to combine 'server' and ${system} and then evaluate as a property name. I'm missing something here.
<property name="server" value="${'server.' + system}" /><!-- TODO make this work -->
<property name="server" value="server.${system}" />
The property::get-value function should be of some help:
<property name="server" value="${property::get-value('server.' + system)}" />