Skip to content

Commit 40babde

Browse files
corda-jenkins-ci02[bot]simon-johnson-r3r3-build
authored
Updated the docs in the persistence service (#1564) (#1567)
The persistence service will do automatic retries as long as some criteria are met in the definitions and use of the entities being persisted. This change makes that clear to CorDapp developers. Co-authored-by: Simon Johnson <[email protected]> Co-authored-by: r3-build <[email protected]>
1 parent d2e483b commit 40babde

File tree

1 file changed

+59
-29
lines changed

1 file changed

+59
-29
lines changed

application/src/main/java/net/corda/v5/application/persistence/PersistenceService.java

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,63 @@ public interface PersistenceService {
1818

1919
/**
2020
* Persists a single {@code entity} to the store.
21+
* There is an automatic transient failure retry mechanism backing this method which can sometimes lead to the persistence
22+
* service internally making multiple requests to persist the same entities. In order that the same entities are not
23+
* erroneously persisted more than once, a de-duplication mechanism is in place to filter duplicate requests that were
24+
* already successful. In order for the persistence service to be able to employ this mechanism, one of the following
25+
* criteria must be met:
26+
* <ul>
27+
* <li>The JPA entity must have an id defined, binding a field to the primary key field in the table, and the value of
28+
* this field provided for the entity must be deterministic at the point the persistence operation is made.
29+
* For example the value should not be populated with a timestamp which would potentially change each time the method
30+
* is called. Note that fields other than the id field in the entity do not have to be deterministic in this case.
31+
* That is you could populate the entity with a stable id, and a different field could hold a timestamp. If this
32+
* persist operation required retries to complete, the value of the non-deterministic field would represent the
33+
* first successful persist operation, for example the first timestamp that made it to the database, even if
34+
* subsequent attempts to retry the persist operation follow.</li>
35+
* <li>For JPA entities with no defined id, the entity must be populated with deterministic values in all its fields.
36+
* If any field were to change if the method were to be called again, for example if it was populated with a
37+
* timestamp, the de-duplication mechanism would fail to recognise this was a duplicate request and more than
38+
* one entity may be persisted.</li>
39+
* </ul>
40+
* It is up to the caller of this function to ensure either one of the above criteria are fulfilled where de-duplication
41+
* of retries is a hard requirement. Otherwise, the caller should expect duplication might occur.
2142
*
2243
* @param entity The entity to persist.
23-
*
24-
* @throws IllegalArgumentException If {@code entity} is a primitive type.
44+
* @throws IllegalArgumentException If {@code entity} is a primitive type.
2545
* @throws CordaPersistenceException If an error occurs during execution.
2646
*/
2747
@Suspendable
2848
void persist(@NotNull Object entity);
2949

3050
/**
3151
* Persists multiple {@code entities} in the persistence context in a single transaction.
52+
* There is an automatic transient failure retry mechanism backing this method which can sometimes lead to the persistence
53+
* service internally making multiple requests to persist the same entities. In order that the same entities are not
54+
* erroneously persisted more than once, a de-duplication mechanism is in place to filter duplicate requests that were
55+
* already successful. In order for the persistence service to be able to employ this mechanism, one of the following
56+
* criteria must be met:
57+
* <ul>
58+
* <li>At least one JPA entity in the list of entities to be persisted must have an id defined, binding a field to the
59+
* primary key field in the table. All entities with id fields must provide deterministic values for these fields
60+
* at the point the persistence operation is made.
61+
* For example no id field should be populated with a timestamp which would potentially change each time the method
62+
* is called. Note that fields other than the id fields in the entities do not have to be deterministic in this case.
63+
* That is you could populate an entity with a stable id, and a different field could hold a timestamp. If this
64+
* persist operation required retries to complete, the value of the non-deterministic field would represent the
65+
* first successful persist operation, for example the first timestamp, even if subsequent attempts to retry the
66+
* persist operation follow.</li>
67+
* <li>Where no JPA entities in the list of entities to be persisted have a defined id, all entities must be populated
68+
* with deterministic values in all fields.
69+
* If any field were to change if the method were to be called again, for example if it was populated with a
70+
* timestamp, the de-duplication mechanism would fail to recognise this was a duplicate request and more than
71+
* one instance of the entities provided may be persisted.</li>
72+
* </ul>
73+
* It is up to the caller of this function to ensure either one of the above criteria are fulfilled where de-duplication
74+
* of retries is a hard requirement. Otherwise, the caller should expect duplication might occur.
3275
*
3376
* @param entities List of entities to be persisted.
34-
*
35-
* @throws IllegalArgumentException If {@code entities} contains any primitive types.
77+
* @throws IllegalArgumentException If {@code entities} contains any primitive types.
3678
* @throws CordaPersistenceException If an error occurs during execution.
3779
*/
3880
@Suspendable
@@ -42,10 +84,8 @@ public interface PersistenceService {
4284
* Merges a single {@code entity} in the persistence context in a transaction.
4385
*
4486
* @param entity The entity to merge.
45-
*
4687
* @return The merged entity.
47-
*
48-
* @throws IllegalArgumentException If {@code entity} is a primitive type.
88+
* @throws IllegalArgumentException If {@code entity} is a primitive type.
4989
* @throws CordaPersistenceException If an error occurs during execution.
5090
*/
5191
@Suspendable
@@ -56,10 +96,8 @@ public interface PersistenceService {
5696
* Merges multiple {@code entities} in the persistence context in a single transaction.
5797
*
5898
* @param entities List of entities to be merged.
59-
*
6099
* @return The list of merged entities.
61-
*
62-
* @throws IllegalArgumentException If {@code entities} contains any primitive types.
100+
* @throws IllegalArgumentException If {@code entities} contains any primitive types.
63101
* @throws CordaPersistenceException If an error occurs during execution.
64102
*/
65103
@Suspendable
@@ -70,8 +108,7 @@ public interface PersistenceService {
70108
* Removes a single {@code entity} from the persistence context in a transaction.
71109
*
72110
* @param entity The entity to remove.
73-
*
74-
* @throws IllegalArgumentException If {@code entity} is a primitive type.
111+
* @throws IllegalArgumentException If {@code entity} is a primitive type.
75112
* @throws CordaPersistenceException If an error occurs during execution.
76113
*/
77114
@Suspendable
@@ -81,8 +118,7 @@ public interface PersistenceService {
81118
* Removes multiple {@code entities} from the persistence context in a single transaction.
82119
*
83120
* @param entities List of entities to be removed.
84-
*
85-
* @throws IllegalArgumentException If {@code entities} contains any primitive types.
121+
* @throws IllegalArgumentException If {@code entities} contains any primitive types.
86122
* @throws CordaPersistenceException If an error occurs during execution.
87123
*/
88124
@Suspendable
@@ -93,11 +129,9 @@ public interface PersistenceService {
93129
* {@code primaryKey}.
94130
*
95131
* @param entityClass The type of entity to find.
96-
* @param primaryKey The primary key of the entity to find.
97-
*
132+
* @param primaryKey The primary key of the entity to find.
98133
* @return The found entity. Null if it could not be found in the persistence context.
99-
*
100-
* @throws IllegalArgumentException If {@code entityClass} is a primitive type.
134+
* @throws IllegalArgumentException If {@code entityClass} is a primitive type.
101135
* @throws CordaPersistenceException If an error occurs during execution.
102136
*/
103137
@Suspendable
@@ -109,10 +143,8 @@ public interface PersistenceService {
109143
*
110144
* @param entityClass The type of the entities to find.
111145
* @param primaryKeys List of primary keys to find with the given {@code entityClass} type.
112-
*
113146
* @return List of entities found. Empty list if none were found.
114-
*
115-
* @throws IllegalArgumentException If {@code entityClass} is a primitive type.
147+
* @throws IllegalArgumentException If {@code entityClass} is a primitive type.
116148
* @throws CordaPersistenceException If an error occurs during execution.
117149
*/
118150
@Suspendable
@@ -124,8 +156,7 @@ public interface PersistenceService {
124156
*
125157
* @param entityClass The type of the entities to find.
126158
* @return A {@link PagedQuery} That returns the list of entities found.
127-
*
128-
* @throws IllegalArgumentException If {@code entityClass} is a primitive type.
159+
* @throws IllegalArgumentException If {@code entityClass} is a primitive type.
129160
* @throws CordaPersistenceException If an error occurs during execution.
130161
*/
131162
@Suspendable
@@ -212,18 +243,17 @@ public interface PersistenceService {
212243
* }
213244
* }</pre></li>
214245
* </ul>
215-
* @param queryName The name of the named query registered in the persistence context.
216-
* @param entityClass The type of the entities to find.
217-
* @param <T> The type of the results.
218246
*
247+
* @param queryName The name of the named query registered in the persistence context.
248+
* @param entityClass The type of the entities to find.
249+
* @param <T> The type of the results.
219250
* @return A {@link ParameterizedQuery} that returns the list of entities found. Empty list if none were found.
220-
*
221251
* @throws IllegalArgumentException If {@code entityClass} is a primitive type.
222252
*/
223253
@Suspendable
224254
@NotNull
225255
<T> ParameterizedQuery<T> query(
226-
@NotNull String queryName,
227-
@NotNull Class<T> entityClass
256+
@NotNull String queryName,
257+
@NotNull Class<T> entityClass
228258
);
229259
}

0 commit comments

Comments
 (0)