You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/02/14 00:11:38 UTC

[isis] branch maint-1.16.1 updated (6d682f6 -> 392d475)

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a change to branch maint-1.16.1
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from 6d682f6  ISIS-1813: adds missing copyright notices
     new a47243f  ISIS-1859: adds a hint-n-tip doc
     new 392d475  ISIS-1860: improves docs regarding CommandReification

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../guides/rgant/_rgant-Action_command.adoc        | 291 ++++++++++++++++-----
 .../guides/rgant/_rgant-Property_command.adoc      | 218 ++++++++++-----
 .../guides/ugodn/_ugodn_hints-and-tips.adoc        |   1 +
 ..._ugodn_hints-and-tips_jdoql-and-timestamps.adoc |  76 ++++++
 4 files changed, 454 insertions(+), 132 deletions(-)
 create mode 100644 adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_hints-and-tips_jdoql-and-timestamps.adoc

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.

[isis] 02/02: ISIS-1860: improves docs regarding CommandReification

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch maint-1.16.1
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 392d475ac421ace05b18128f10cb2dea543aeba0
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Feb 14 00:11:31 2018 +0000

    ISIS-1860: improves docs regarding CommandReification
---
 .../guides/rgant/_rgant-Action_command.adoc        | 291 ++++++++++++++++-----
 .../guides/rgant/_rgant-Property_command.adoc      | 218 ++++++++++-----
 2 files changed, 377 insertions(+), 132 deletions(-)

diff --git a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_command.adoc b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_command.adoc
index 9665b22..f03d9a8 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_command.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_command.adoc
@@ -1,15 +1,21 @@
 [[_rgant-Action_command]]
-= `command()`
+= Command Persistence and Processing
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :_basedir: ../../
 :_imagesdir: images/
 
 
-The `@Action(command=...)` attribute (and the related `@Action(commandXxx=...)` attributes) allows an action invocation to be made into a concrete object such that it can be inspected and persisted.
-The primary use case for this are to support the deferring the execution of the action such that it can be invoked in the background, and to replay commands in a master/slave configuration.
+Every action invocation (and property edit for that matter) is automatically reified into a concrete `Command` object.
+The `@Action(command=..., commandXxx=...)` attributes provide hints for the persistence of that `Command` object, and the subsequent processing of that persisted command.
+The primary use cases for this are to support the deferring the execution of the action such that it can be invoked in the background, and to replay commands in a master/slave configuration.
 
+Note that for a `Command` to actually be persisted requires an appropriate implementation of `CommandService` SPI.
+The framework does _not_ provide an implementation of this SPI "out-of-the-box".
+However, the (non-ASF) Incode Platform's link:http://platform.incode.org/modules/spi/command/spi-command.html[ command module]) _does_ provide such an implementation.
 
 
+== Design
+
 The annotation works with (and is influenced by the behaviour of) a number of domain services:
 
 * xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`]
@@ -18,7 +24,7 @@ The annotation works with (and is influenced by the behaviour of) a number of do
 * xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-spi_BackgroundCommandService[`BackgroundCommandService`]
 
 
-Each action invocation is reified by the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service into a `Command` object, capturing details of the target object, the action, the parameter arguments, the user, a timestamp and so on.
+Each action invocation is automatically reified by the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service into a `Command` object, capturing details of the target object, the action, the parameter arguments, the user, a timestamp and so on.
 
 If an appropriate `CommandService` is configured (for example using (non-ASF) link:http://platform.incode.org/modules/spi/command/spi-command.html[Incode Platform's command] module), then the `Command` itself is persisted.
 
@@ -32,79 +38,240 @@ If background ``Command``s are used, then an external scheduler, using xref:../u
 
 
 
-The `command()` attribute determines whether the action invocation should be reified into a `Command` object (by the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service).
-
-The default is `AS_CONFIGURED`, meaning that the xref:../rgcfg/rgcfg.adoc#_rgcfg_configuring-core[configuration property] `isis.services.command.actions` is used to determine whether the action invocation is reified:
-
-* `all` +
-+
-all action invocations are reified
-
-* `ignoreSafe` (or `ignoreQueryOnly`) +
-+
-invocations of actions with safe (read-only) semantics are ignored, but actions which may modify data are not ignored
-
-* `none` +
-+
-no action invocations are reified.
-
-If there is no configuration property in `isis.properties` then all action invocations are reified into ``Command``s.
-
-[NOTE]
-====
-Note: `Command` reification does not necessarily imply that `Command` objects will be persisted; that depends on whether there is a xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-spi_CommandService[`CommandService`] configured that will persist said ``Command``s.
-====
-
-This default can be overridden on an action-by-action basis; if `command()` is set to `ENABLED` then the action is reified irrespective of the configured value; if set to `DISABLED` then the action invocation is NOT reified irrespective of the configured value.
+[[_rgant-Action_commandPersistence]]
+== `command()` and `commandPersistence()`
+
+The `command()` and `commandPersistence() attributes work together to determine whether a command will actually be persisted.
+There inter-relationship is somewhat complex, so is probably best explained by way of examples:
+
+[cols="1a,1a,1a,1a,1a,2a", options="header"]
+|===
+
+| `command()`
+|`isis.services.
+command.actions` config property
+| action's declared `semantics()`
+| `command
+Persistence()`
+| action dirties objects?
+| is command persisted?
+
+| `ENABLED`
+| (any)
+| (any)
+| `PERSISTED`
+| (either)
+| yes
+
+| `ENABLED`
+| (any)
+| (any)
+| `IF_HINTED`
+| no
+| no
+
+| `ENABLED`
+| (any)
+| (any)
+| `IF_HINTED`
+| yes
+| yes
+
+| `ENABLED`
+| (any)
+| (any)
+| `NOT_PERSISTED`
+| (any)
+| no
+
+| `AS_CONFIGURED`
+| `all`
+| (any)
+| `PERSISTED`
+| no
+| yes
+
+| `AS_CONFIGURED`
+| `all`
+| (any)
+| `IF_HINTED`
+| no
+| no
+
+| `AS_CONFIGURED`
+| `all`
+| (any)
+| `IF_HINTED`
+| yes
+| yes
+
+| `AS_CONFIGURED`
+| `all`
+| (any)
+| `NOT_PERSISTED`
+| (any)
+| no
+
+| `AS_CONFIGURED`
+| `ignoreSafe` or `ignoreQueryOnly`
+| `SAFE`
+| `PERSISTED`
+| no
+| no (!)
+
+| `AS_CONFIGURED`
+| `ignoreSafe` or `ignoreQueryOnly`
+| `SAFE`
+| `IF_HINTED` or `NOT_PERSISTED`
+| no
+| no
+
+| `AS_CONFIGURED`
+| `ignoreSafe` or `ignoreQueryOnly`
+| `SAFE`
+| `PERSISTED` or `IF_HINTED`
+| yes
+| yes
+
+| `AS_CONFIGURED`
+| `ignoreSafe` or `ignoreQueryOnly`
+| `SAFE`
+| `NOT_PERSISTED`
+| yes
+| yes (!)
+
+| `AS_CONFIGURED`
+| `ignoreSafe` or `ignoreQueryOnly`
+| `IDEMPOTENT` or `NON_IDEMPOTENT`
+| `PERSISTED`
+| (any)
+| yes
+
+| `AS_CONFIGURED`
+| `ignoreSafe` or `ignoreQueryOnly`
+| `IDEMPOTENT` or `NON_IDEMPOTENT`
+| `IF_HINTED`
+| no
+| no
+
+| `AS_CONFIGURED`
+| `ignoreSafe` or `ignoreQueryOnly`
+| `IDEMPOTENT` or `NON_IDEMPOTENT`
+| `IF_HINTED`
+| yes
+| yes
+
+| `AS_CONFIGURED`
+| `ignoreSafe` or `ignoreQueryOnly`
+| `IDEMPOTENT` or `NON_IDEMPOTENT`
+| `NOT_PERSISTED`
+| (any)
+| no
+
+| `AS_CONFIGURED`
+| `none`
+| (any)
+| `PERSISTED`
+| no
+| no (!)
+
+| `AS_CONFIGURED`
+| `none`
+| (any)
+| `PERSISTED`
+| yes
+| yes
+
+| `AS_CONFIGURED`
+| `none`
+| (any)
+| `IF_HINTED`
+| no
+| no
+
+| `AS_CONFIGURED`
+| `none`
+| (any)
+| `IF_HINTED`
+| yes
+| yes
+
+| `AS_CONFIGURED`
+| `none`
+| (any)
+| `NOT_PERSISTED`
+| no
+| no
+
+| `AS_CONFIGURED`
+| `none`
+| (any)
+| `NOT_PERSISTED`
+| yes
+| yes (!)
+
+| `DISABLED`
+| (any)
+| (any)
+| `PERSISTED`
+| no
+| no (!)
+
+| `DISABLED`
+| (any)
+| (any)
+| `PERSISTED`
+| yes
+| yes
+
+| `DISABLED`
+| (any)
+| (any)
+| `IF_HINTED`
+| no
+| no
+
+| `DISABLED`
+| (any)
+| (any)
+| `IF_HINTED`
+| yes
+| yes
+
+| `DISABLED`
+| (any)
+| (any)
+| `NOT_PERSISTED`
+| no
+| no
+
+| `DISABLED`
+| (any)
+| (any)
+| `NOT_PERSISTED`
+| yes
+| yes (!)
+
+|===
 
 For example:
 
 [source,java]
 ----
 public class Order {
-    @Action(command=CommandReification.ENABLED)
-    public Invoice generateInvoice(...) { ... }
-}
-----
-
-corresponds to the behaviour described above; the `Command` object is persisted (assuming an appropriate `CommandService` is defined, and executed immediately in the foreground).
-
-
-
-
-== `commandPersistence()`
-
-If the action invocation has been reified, then the `commandPersistence()` attribute determines whether that `Command` object should then also be persisted (the default), or not persisted, or only if hinted.
-
-To explain this last alternative:
-
-[source,java]
-----
-public class Order {
     @Action(
         command=CommandReification.ENABLED,
-        commandPersistence=CommandPersistence.IF_HINTED
+        commandPersistence=CommandPersistence.PERSISTED
     )
     public Invoice generateInvoice(...) { ... }
 }
 ----
 
-will suppress the persistence of the `Command` object _unless_ a child background `Command` has been created in the body of the action by way of the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_BackgroundService[`BackgroundService`].
-
-On the other hand:
+As can be seen, whether a command is actually persisted does not always follow the value of the `commandPersistence()` attribute.
+This is because the `command()` attribute actually determines whether any command metadata for the action is captured within the framework's internal metamodel.
+If `command` is `DISABLED` or does not otherwise apply due to the action's declared semantics, then the framework decides to persist a command based solely on whether the action dirtied any objects (as if `commandPersistence()` was set to `IF_HINTED`).
 
-[source,java]
-----
-public class Order {
-    @Action(
-        command=CommandReification.ENABLED,
-        commandPersistence=CommandPersistence.NOT_PERSISTED
-    )
-    public Invoice generateInvoice(...) { ... }
-}
-----
 
-will prevent the parent `Command` object from being persisted, _even if_ a child background `Command` is created.
 
 
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Property_command.adoc b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Property_command.adoc
index 99be07d..ecfc3b7 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Property_command.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Property_command.adoc
@@ -1,14 +1,16 @@
 [[_rgant-Property_command]]
-= `command()`
+= Command Persistence and Processing
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :_basedir: ../../
 :_imagesdir: images/
 
 
-The `@Property(command=...)` attribute (and the related `@Property(commandXxx=...)` attributes) allows a property edit to be made into a concrete object such that it can be inspected and persisted.
-The primary use case for this are to support the deferring the execution of the action such that it can be invoked in the background, and to replay commands in a master/slave configuration.
+Every property edit (and action invocation for that matter) is automatically reified into a concrete `Command` object.
+The `@Property(command=..., commandXxx=...)` attributes provide hints for the persistence of that `Command` object, and the subsequent processing of that persisted command.
+The primary use cases for this are to support the deferring the execution of the action such that it can be invoked in the background, and to replay commands in a master/slave configuration.
 
 
+== Design
 
 The annotation works with (and is influenced by the behaviour of) a number of domain services:
 
@@ -18,7 +20,7 @@ The annotation works with (and is influenced by the behaviour of) a number of do
 * xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-spi_BackgroundCommandService[`BackgroundCommandService`]
 
 
-Each property edit is reified by the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service into a `Command` object, capturing details of the target object, the property, the proposed new value fo the property, the user, a timestamp and so on.
+Each property edit is automatically reified by the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service into a `Command` object, capturing details of the target object, the property, the proposed new value fo the property, the user, a timestamp and so on.
 
 If an appropriate `CommandService` is configured (for example using (non-ASF) link:http://platform.incode.org/modules/spi/command/spi-command.html[Incode Platform's command] module), then the `Command` itself is persisted.
 
@@ -30,86 +32,162 @@ If there is an implementation of `BackgroundCommandService` (as the (non-ASF) li
 If background ``Command``s are used, then an external scheduler, using xref:../ugbtb/ugbtb.adoc#_ugbtb_headless-access_BackgroundCommandExecution[headless access], must also be configured.
 ====
 
-
-
-The `command()` attribute determines whether the property edit should be reified into a `Command` object (by the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service).
-
-The default is `AS_CONFIGURED`, meaning that the xref:../rgcfg/rgcfg.adoc#_rgcfg_configuring-core[configuration property] `isis.services.command.properties` is used to determine whether the property edit is reified:
-
-* `all` +
-+
-all property edits are reified
-
-* `none` +
-+
-no property edits are reified.
-
-If there is no configuration property in `isis.properties` then all property edits are reified into ``Command``s.
-
-[NOTE]
-====
-Note: `Command` reification does not necessarily imply that `Command` objects will be persisted; that depends on whether there is a xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-spi_CommandService[`CommandService`] configured that will persist said ``Command``s.
-====
-
-This default can be overridden on an property-by-property basis; if `command()` is set to `ENABLED` then the action is reified irrespective of the configured value; if set to `DISABLED` then the property edit is NOT reified irrespective of the configured value.
+[[_rgant-Property_commandPersistence]]
+== `command()` and `commandPersistence()`
+
+The `command()` and `commandPersistence() attributes work together to determine whether a command will actually be persisted.
+There inter-relationship is somewhat complex, so is probably best explained by way of examples:
+
+[cols="1a,1a,1a,1a,2a", options="header"]
+|===
+
+| `command()`
+|`isis.services.
+command.properties` config property
+| `command
+Persistence()`
+| action dirties objects?
+| is command persisted?
+
+| `ENABLED`
+| (any)
+| `PERSISTED`
+| (either)
+| yes
+
+| `ENABLED`
+| (any)
+| `IF_HINTED`
+| no
+| no
+
+| `ENABLED`
+| (any)
+| `IF_HINTED`
+| yes
+| yes
+
+| `ENABLED`
+| (any)
+| `NOT_PERSISTED`
+| (any)
+| no
+
+| `AS_CONFIGURED`
+| `all`
+| `PERSISTED`
+| no
+| yes
+
+| `AS_CONFIGURED`
+| `all`
+| `IF_HINTED`
+| no
+| no
+
+| `AS_CONFIGURED`
+| `all`
+| `IF_HINTED`
+| yes
+| yes
+
+| `AS_CONFIGURED`
+| `all`
+| `NOT_PERSISTED`
+| (any)
+| no
+
+| `AS_CONFIGURED`
+| `none`
+| `PERSISTED`
+| no
+| no (!)
+
+| `AS_CONFIGURED`
+| `none`
+| `PERSISTED`
+| yes
+| yes
+
+| `AS_CONFIGURED`
+| `none`
+| `IF_HINTED`
+| no
+| no
+
+| `AS_CONFIGURED`
+| `none`
+| `IF_HINTED`
+| yes
+| yes
+
+| `AS_CONFIGURED`
+| `none`
+| `NOT_PERSISTED`
+| no
+| no
+
+| `AS_CONFIGURED`
+| `none`
+| `NOT_PERSISTED`
+| yes
+| yes (!)
+
+| `DISABLED`
+| (any)
+| `PERSISTED`
+| no
+| no (!)
+
+| `DISABLED`
+| (any)
+| `PERSISTED`
+| yes
+| yes
+
+| `DISABLED`
+| (any)
+| `IF_HINTED`
+| no
+| no
+
+| `DISABLED`
+| (any)
+| `IF_HINTED`
+| yes
+| yes
+
+| `DISABLED`
+| (any)
+| `NOT_PERSISTED`
+| no
+| no
+
+| `DISABLED`
+| (any)
+| `NOT_PERSISTED`
+| yes
+| yes (!)
+
+|===
 
 For example:
 
 [source,java]
 ----
 public class Order {
-    @Property(command=CommandReification.ENABLED)
-    public Product getProduct() { ... }
-    public void setProduct(Product p) { ... }
-}
-----
-
-corresponds to the behaviour described above; the `Command` object is persisted (assuming an appropriate `CommandService` is defined, and executed immediately in the foreground).
-
-
-
-
-== `commandPersistence()`
-
-If the property edit has been reified, then the `commandPersistence()` attribute determines whether that `Command` object should then also be persisted (the default), or not persisted, or only if hinted.
-
-To explain this last alternative:
-
-[source,java]
-----
-public class Order {
     @Property(
         command=CommandReification.ENABLED,
-        commandPersistence=CommandPersistence.IF_HINTED
+        commandPersistence=CommandPersistence.PERSISTED
     )
     public Product getProduct() { ... }
     public void setProduct(Product p) { ... }
 }
 ----
 
-will suppress the persistence of the `Command` object _unless_ a child background `Command` has been created in the body of the property by way of the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_BackgroundService[`BackgroundService`].
-
-[NOTE]
-====
-Unlike actions, where this is quite feasible, it is rather unlikely to occur as a side-effect of editing a property.
-====
-
-On the other hand:
-
-[source,java]
-----
-public class Order {
-    @Property(
-        command=CommandReification.ENABLED,
-        commandPersistence=CommandPersistence.NOT_PERSISTED
-    )
-    public Product getProduct() { ... }
-    public void setProduct(Product p) { ... }
-}
-----
-
-will prevent the parent `Command` object from being persisted, _even if_ a child background `Command` is created.
-
+As can be seen, whether a command is actually persisted does not always follow the value of the `commandPersistence()` attribute.
+This is because the `command()` attribute actually determines whether any command metadata for the action is captured within the framework's internal metamodel.
+If `command` is `DISABLED` or does not otherwise apply due to the action's declared semantics, then the framework decides to persist a command based solely on whether the action dirtied any objects (as if `commandPersistence()` was set to `IF_HINTED`).
 
 
 

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.

[isis] 01/02: ISIS-1859: adds a hint-n-tip doc

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch maint-1.16.1
in repository https://gitbox.apache.org/repos/asf/isis.git

commit a47243ff9fb6aac28d9a4b80b807fb0693216532
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Feb 13 23:03:22 2018 +0000

    ISIS-1859: adds a hint-n-tip doc
---
 .../guides/ugodn/_ugodn_hints-and-tips.adoc        |  1 +
 ..._ugodn_hints-and-tips_jdoql-and-timestamps.adoc | 76 ++++++++++++++++++++++
 2 files changed, 77 insertions(+)

diff --git a/adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_hints-and-tips.adoc b/adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_hints-and-tips.adoc
index a85c7e5..17bf778 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_hints-and-tips.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_hints-and-tips.adoc
@@ -32,5 +32,6 @@ include::_ugodn_hints-and-tips_java8.adoc[leveloffset=+1,lines=3..-1]
 
 include::_ugodn_hints-and-tips_diagnosing-n-plus-1.adoc[leveloffset=+1,lines=3..-1]
 include::_ugodn_hints-and-tips_typesafe-queries-and-fetchgroups.adoc[leveloffset=+1,lines=3..-1]
+include::_ugodn_hints-and-tips_jdoql-and-timestamps.adoc[leveloffset=+1,lines=3..-1]
 
 // end::inclusions[]
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_hints-and-tips_jdoql-and-timestamps.adoc b/adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_hints-and-tips_jdoql-and-timestamps.adoc
new file mode 100644
index 0000000..dad1ca5
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_hints-and-tips_jdoql-and-timestamps.adoc
@@ -0,0 +1,76 @@
+:_basedir: ../../
+:_imagesdir: images/
+[[_ugodn_hints-and-tips_jdoql-and-timestamps]]
+= JDOQL and Timestamps
+:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
+
+
+Beware of entities with a property called "timestamp": you run the risk of "timestamp" being treated as a keyword in certain contexts, probably not as you intended.
+
+By way of example, the (non-ASF) link:http://platform.incode.org[Incode Platform]'s command module has an entity called `CommandJdo`.
+This has a property called "timestamp", of type `java.sql.Timestamp`.
+
+This defines a query using JDOQL:
+
+[source,java]
+----
+SELECT
+FROM org.isisaddons.module.command.dom.CommandJdo
+WHERE executeIn == 'FOREGROUND'
+   && timestamp > :timestamp
+   && startedAt != null
+   && completedAt != null
+ORDER BY timestamp ASC
+----
+
+This is declared using a JDO `@Query`; no errors are thrown at any stage.
+
+However, running this query against SQL Server 2016 produced a different result first time it was run compared to subsequent times.
+
+Running SQL Profiler showed the underlying SQL as:
+
+[source,sql]
+----
+exec sp_prepexec @p1 output,N'@P0 datetime2',
+N'SELECT ''org.isisaddons.module.command.dom.CommandJdo'' AS NUCLEUS_TYPE,
+  A0.arguments,
+  ...,
+  A0.target,
+  A0."timestamp",
+  A0.transactionId,
+  A0."user",
+  ''2018-01-24 17:29:18.3'' AS NUCORDER0    // <1>
+FROM isiscommand.Command A0
+WHERE A0.executeIn = ''FOREGROUND''
+  AND A0."timestamp" > @P0
+  AND A0.startedAt IS NOT NULL
+  AND A0.completedAt IS NOT NULL
+  ORDER BY NUCORDER0
+  OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY ',   // <2>
+'2018-01-24 17:29:18.3000000'               // <3>
+----
+<1> discussed below ... this is the issue
+<2> because the query is submitted with max rows programmatically set to 2.
+<3> argument for @P0 (the timestamp parametr)
+
+
+To unpick this, the key issue is the `NUCORDER0` column, which is then used in the `ORDER BY`.
+However, because this is a literal value, the effect is no defined ordering.
+
+The problem therefore is that in the JDOQL the "ORDER BY timestamp ASC", the "timestamp" is being evaluated as the current time - a built-in function.
+
+My fix was to change the JDOQL to be:
+
+[source,sql]
+----
+SELECT
+FROM org.isisaddons.module.command.dom.CommandJdo
+WHERE executeIn == 'FOREGROUND'
+   && timestamp > :timestamp
+   && startedAt != null
+   && completedAt != null
+ORDER BY this.timestamp ASC             // <1>
+----
+<1> Use "this." to qualify the timestamp
+
+It wasn't necessary to qualify the other occurances of "timestamp" (though it would be no harm to do so, either).

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.