Replies: 4 comments 12 replies
-
|
Thank you for the idea. The same applies to the use case of a user obtained from the cache but in the meantime removed externally (e.g. from LDAP) - once the fields in the LDAP object would be accessed that are not stored in this cache, it would be the same situation of a partially loaded object and the same measures should apply. Hence I agree that the case of partially loaded model should be clearly signalled to the caller. Before going forward, it is important to understand where the raising and handling the exception takes place. From that we will get the right exception parent (whether it should be a Could you please add the following information for a client use case (mentioned in the description) and user use case (mentioned here):
|
Beta Was this translation helpful? Give feedback.
-
|
The What is the value of introducing the I like the idea of extending <M, R> Stream<R> ModelToRepresentation.toRepresentation(Stream<M> models, Function<M, R> transformer) {
return models.map(m -> try { return transformer(m);} catch (ModelIllegalStateException e) { return null; })
.filter(Objects::nonNull);
}
This need not be the removal, but for certain the entity supporting the model became illegal. The entity may become illegal by expiring or other ways, so we should not concentrate only on a single painpoint of now. That's why As for the transient error indicator, I agree we can postpone this discussion for now. |
Beta Was this translation helpful? Give feedback.
-
|
Introducing the Optional makes the code more readable IMHO; I like to avoid returning nulls. I wanted to make it explicit that the transformation returns one instance or no instance. Whether the short-lived streams are a performance penalty or not would be hard for me to tell without a JMH test. At the same time the function you propose is elegant and readable, and with some JavaDoc to indicate that the transformation can return null it is good to go for me. To better understand the |
Beta Was this translation helpful? Give feedback.
-
|
GitHub issue created and assigned to me: #9645 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Problem statement
When accessing data from Keycloak (either read or write), there can be different kinds of problems, usually in the kind of transactions failing, database constraints violated, lazy loading issues.
In the example of the JPA map storage when listing all the clients for a REST Admin API caller, it first reads a subset of the fields for performance reasons. Later, when retrieving all details, it will fetch the additional fields. In this case the record in the table could have been deleted or modified.
It could be seen when running ConcurrencyTest#createRemoveClient() with a JPA map storage configuration: The server returns a 500 error when retrieving a list of clients while one of the clients in the list is removed by another client concurrently.
Approach
When the JPA map storage provider recognizes that the entity has been removed from the database, it should throw an exception that extends the ModelException (for example: ObjectRemovedException). The ClientResource#getClients() could then catch the exception and filter the instance from the list.
There seems to be an existing handling of exceptions in place, although it is
try { c.getClientId(); return true; } catch (Exception ex) { return false; })In the mid-term there might be additional exceptions like ObjectModifiedException for optimistic locking exceptions. In that case the ClientResource will be more difficult to recover and would most likely pass a 500 error to the caller.
Benefits
The caller would retrieve a list of valid clients even if one client of the list is removed concurrently.
Alternatives
The caller could receive a 500 exception. The caller would then still additional information if the problem is a transient problem and when to retry the call.
Beta Was this translation helpful? Give feedback.
All reactions