How to update a WCF OData service-based entity without System.DateTime format exception?

400 views
Skip to first unread message

Izochrone

unread,
Nov 11, 2012, 8:54:20 AM11/11/12
to odata4j...@googlegroups.com
Hi,

I just started to use odata4j on Android, and I managed to read data from a WCF-based Odata data source.
I'd like to change one of the entity's single String property, but I (surprisingly) get a message about this:
"Caused by: org.odata4j.exceptions.BadRequestException: Error processing request stream. Error encountered in converting the value from request payload for property 'BDate' to type 'System.DateTime', which is the property's expected type. See inner exception for more detail.'"

  ODataConsumer c = ODataJerseyConsumer.newBuilder(ListActivity.url)
.setFormatType(FormatType.ATOM).build();
ODataJerseyConsumer.dump.all(true);
  OEntity ent = c.getEntity(entitySetName, localObject.ID).execute();
System.out.println("Actual key - " + ent.getEntityKey());
System.out
  .println("objType - " + ent.getProperty("BDate").getClass());
System.out
  .println("objValue - " + ent.getProperty("BDate").getValue());
c.updateEntity(ent)
  .properties(OProperties.string("Name", localObject.Name + "2")).execute();

The object class for the problematic DateTime object is org.odata4j.core.OProperties$Impl, and it's value: 1994-11-03T00:00:00.000
I don't understand why it tries to update that value (I just want to update the Name), too, and if does, why throws exception (I simply try to put back the object I just read from the data source).
Can you help me?

John Spurlock

unread,
Nov 11, 2012, 8:59:05 AM11/11/12
to odata4j...@googlegroups.com
More interesting would be to look at the property's edm type.  ent.getProperty("BDate").getType()

I suspect you are trying to update a datetime property with a string value.  Use OProperties.datetime to create Edm.DateTime property values.  OProperties.string will create property values of type Edm.String

Izochrone

unread,
Nov 11, 2012, 9:05:47 AM11/11/12
to odata4j...@googlegroups.com
The Type is :  EdmSimpleType[Edm.DateTime]

What is it supposed to be? And why does it want to update that field, too?

John Spurlock

unread,
Nov 11, 2012, 9:10:00 AM11/11/12
to odata4j...@googlegroups.com
updateEntity updates all properties.  mergeEntity updates individual properties.  

Can you set ODataConsumer.dump.all(true) before running this, then send me the request/response trail?

Also which version of odata4j are you using?

Izochrone

unread,
Nov 11, 2012, 9:22:58 AM11/11/12
to odata4j...@googlegroups.com
I'm using odata4j 0.7.0.
I tried to use mergeEntity, and it was working :)
I am glad, you replied so soon, it is appreciated.

I didn't know, that updateEntity updates each property but it is still strange that unchanged properties can't be saved.

My project does this:
Reads from the server (WCF Odata source)
Displays the list of the result
Lets pick anyone from the list, show some of its details (no all, it has over 50 properties)
The changed values should be stored (I am thinking to store it on the phone first then do a mass-save - it is not implemented yet)
Saves the changed values back to server 

Do you still need the save's response trail?

John Spurlock

unread,
Nov 11, 2012, 9:26:25 AM11/11/12
to odata4j...@googlegroups.com
Yes I'd like to track down the cause of the updateEntity problem.  As you say, that should work just as well.

That error is coming from the WCF server, if you wouldn't mind sending me the request/response trace from the updateEntity scenario, it would help us debug to see if it's something we have to workaround or is a bug on our end.

Izochrone

unread,
Nov 11, 2012, 9:51:22 AM11/11/12
to odata4j...@googlegroups.com
Yes, I send it, but only for you, as it contains sensitive data (I changed them but doesn't want to send it publicly)

There is a bonus question :)
The main table has a side table and they are connected via a connector table (their PKs are stored there). Is it possible to load the side table's data when I read the main data (unfortunately there are no FKs)?

John Spurlock

unread,
Nov 11, 2012, 10:05:29 AM11/11/12
to odata4j...@googlegroups.com
If the relationship is defined in the model, you can use $expand (OQueryRequest#expand in the odata4j consumer api).

John Spurlock

unread,
Nov 11, 2012, 10:13:46 AM11/11/12
to odata4j...@googlegroups.com
GET response: <d:DateProp m:type="Edm.DateTime">1994-11-03T00:00:00</d:DateProp>
Internal representation: 1994-11-03T00:00:00.000
PUT request <d:DateProp m:type="Edm.DateTime">1994-11-03T00:00</d:DateProp>    <-- note the lack of seconds

The PUT request value is valid according to the spec [1].  The server should accept it.  Which version of WCF is providing the server implementation?



On Sun, Nov 11, 2012 at 9:51 AM, Izochrone <izoc...@gmail.com> wrote:

Izochrone

unread,
Nov 11, 2012, 10:19:45 AM11/11/12
to odata4j...@googlegroups.com
I can't access the server directly, so I just assume it uses either .Net 4.0 or .Net 4.5.
Does it help?

John Spurlock

unread,
Nov 11, 2012, 10:50:10 AM11/11/12
to odata4j...@googlegroups.com
I was able to repro using WCF DS 5.1.0 locally.  Looks like this a bug in all versions of WCF DS - we may need to provide a workaround in odata4j.

Izochrone

unread,
Nov 11, 2012, 11:28:29 AM11/11/12
to odata4j...@googlegroups.com
I don't know if Microsoft is aware of that problem. Probably it'd be wise to let them know :)

John Spurlock

unread,
Nov 11, 2012, 11:29:44 AM11/11/12
to odata4j...@googlegroups.com
Did you happen to notice the last comment on that product forum thread?

Izochrone

unread,
Nov 11, 2012, 11:49:39 AM11/11/12
to odata4j...@googlegroups.com
I just did :)
I hope, they will fix this. 
Thanks for your work, it helped me a lot.

John Spurlock

unread,
Nov 11, 2012, 11:50:36 AM11/11/12
to odata4j...@googlegroups.com
No problem, thanks for reporting it - as it sounds like we'll need to take some action on the odata4j side in the meantime.

Philipp Sebastian Thun

unread,
Nov 12, 2012, 3:44:16 AM11/12/12
to odata4j...@googlegroups.com
I agree; we should introduce some kind of workaround for odata4j. But I do not think that it would be a good idea to simply remove the stripping of zeros for all use cases as the same code is shared for the server part as well and I actually would like to keep the odata4j producer side to be compliant to the specification. Any ideas for a workaround?

John Spurlock

unread,
Nov 12, 2012, 6:24:26 AM11/12/12
to odata4j...@googlegroups.com
Philipp, can you give a pointer to the spec where it says zeros should be stripped?

Philipp Sebastian Thun

unread,
Nov 12, 2012, 7:49:09 AM11/12/12
to odata4j...@googlegroups.com
The OData specification (V2) defines "Common Serialization Rules for XML-Based Formats" (section 2.2.6.1). For Edm.DateTime there is a reference to another section: "See dateTimeLiteral in the Literal Form of Entity Data Model Primitive Types table in Abstract Type System (section 2.2.2)."

Section 2.2.2 (Abstract Type System) provides the following specification (as ABNF grammar rule): dateTimeLiteral = year "-" month "-" day "T" hour ":" minute [":" second ["." nanoSeconds]]

John Spurlock

unread,
Nov 12, 2012, 7:59:19 AM11/12/12
to odata4j...@googlegroups.com
Right, so we're technically valid - but is there a place that recommends stripping off zero values?  In my opinion, the ABNF alone does not constitute a recommendation to do this.

If not, we may need to at least keep the seconds place to be compatible with WCF DS.

This is important, as it breaks a very simple consumer scenario (update an entity just retrieved that happens to have a datetime property).  We should consider cherry-picking a fix branching off 0.7 for a 0.7.1 release.

Philipp Sebastian Thun

unread,
Nov 15, 2012, 12:07:44 PM11/15/12
to odata4j...@googlegroups.com
I did not find any recommendation on doing so. To not break this simple use case, we should proceed as you suggested.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages