Axon - How to get #QueryHandler handle method to return a k,v Map - axon

I need to return a k,v map
Map<String,UserProfile>
Similar to how I query for a List.
queryGateway.query(q, ResponseTypes.multipleInstancesOf(UserProfile.class)
That works with a handler that returns a map.
#QueryHandler
Map<String, UserProfile> handle(UserProfileQuery query) {
return userProfileRepository.getUserProfiles(query.getUserIds());
}
Using Axon 4.2

At the moment (meaning version 4.3.1 of framework), the answer is rather simple Stephen.
You cannot return a Map<K, V> directly from an #QueryHandler annotated function.
It's currently an issue on Axon Framework's GitHub page, which you can find here.
Most pragmatic solution for now, is to provide a wrapper class containing the Map<K, V> you want to return.
Or, likely, a Collection of entries is what you are looking for, as you are suggesting to use the ResponseTypes#multipleInstancesOf(Class) function.
It's the entry object you'd have to create yourself in this case.
Hope this helps!

Related

Dart: Code design for interface to construct objects from HTTP requests

I'm trying to implement an abstract base class for objects that will be parsed from HTTP calls. The goals is to create a CachedFuture<T> class that, when accessed, makes an HTTP call to get the object and caches the result.
My inclination was to implement the classes as follows:
class HTTPGetable<T extends HTTPGetable<T>> {
static Future<T> httpGet(int id);
}
class CachedFuture<T extends HTTPGetable<T>> {
int _id;
Future<T?>? _cachedResult;
bool _has_already_made_request;
CachedFuture({required int this._id});
Future<T?> get() {
if(this._cachedResult == null)
try {
this._cachedResult = T.httpGet(this._id);
} except {
// parse error or other error
this._cachedResult = CompletableFuture.completedFuture(null);
}
}
return this._cachedResult;
}
}
The intuition here is that there are a lot of objects with "pointers" to other objects in the database on the backend. It doesn't make sense to follow every pointer when constructing objects to return in the HttpRequest, so my intent is to wrap "pointers" in this CachedFuture class.
This should enable someone to "follow" one of these "pointers" without ever having to worry about caching the http request or about the specifics of constructing that request. Hopefully this provides another level of abstraction for the user of the class so they can right code that's agnostic to what's going on under the hood.
However, static interfaces aren't in Dart, so this pattern doesn't work. My intuition is that this is a sign I should be using a different pattern instead of trying to force my way.
httpGet is basically a factory method, but the functionality of CachedFuture needs a way to look up the factory from the type, so I don't immediately see a good way to implement a true factory either.
Could anyone recommend a good programming pattern for solving this? I imagine it's a pretty common usecase for both http requests and database requests.
Update: The best workaround I've found is to do different "factories" to httpGet each T, then use reflection to look up the appropriate factory. However, as the description sounds, this seems pretty convoluted & error prone, so I'm still convinced that there's almost certainly a better pattern to use.
Can't you just create the abstract class CachedFuture along the lines of what you wrote, with an abstract method httpGet(int id) to be implemented by the subclass?
If there is only ever one instance of an object of type <T extends CachedFuture> then you could consider making the subclass a Singleton.
Apologies if I misunderstood your question!

SonarQube complains about using ResponseEntity with a wildcard

I use SpringBoot for REST web services development and SonarQube for static analysis.
I have a few endpoints in my application that look the following way:
#PostMapping
ResponseEntity<?> addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
SonarQube complains about using ResponseEntity with a wildcard, reporting me a Critical issue "Generic wildcard types should not be used in return parameters".
I wonder if I should disable this verification in SonarQube or come up with something different for return type for these cases.
What do you think about it?
#PostMapping
ResponseEntity<Object> addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
This will also remove the error. It is still very generic, but it is one of the solutions if you want to return different types based on the outcome. For instance:
#PostMapping
ResponseEntity<Object> addSomething(#RequestBody Some object) {
//Will return ResponseEntity<> with errors
ResponseEntity<Object> errors = mapValidationService(bindingResult);
if (!ObjectUtils.isEmpty(errors)) return errors;
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
So actually i find the rule pretty self describing:
Using a wildcard as a return type implicitly means that the return value should be considered read-only, but without any way to enforce this contract.
Let's take the example of method returning a "List". Is it possible on this list to add a Dog, a Cat, ... we simply don't know. The consumer of a method should not have to deal with such disruptive questions.
https://sonarcloud.io/organizations/default/rules#rule_key=squid%3AS1452
So Actually in your case, you do not want any kind of Class in there, you specifically want an Serializable-object - for obvious reasons: it should be serialized later on
So instead of using ? it would be more suitable in your case to use Serializable. This is always case dependent, but normally you definitly expect some kind of common interface or base class as a return value. Hence that, the follow up developer, definitly knows what he can expect, and what kind of functionality he definitly can use.
Finally I've removed <?> from return value, so the code looks like the following now:
#PostMapping
ResponseEntity addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
SonarQube doesn't complain anymore and code seems a little bit simpler now.

Create key with objectify

Calling Objectify method:
Key.create(ParentClass.class parentClass, KindClass.class kindClass, String id)
for the exactly same parameters twice at the same time, I got:
name=UWxoCs7KpxDu2fYBI3s2fkOq-wM
name=jOqQzhZzAScJ0O3OEtYF3jzb34Q
Does this method need to run in a transaction so I get a predictable result?
The app id and namespace are also encoded in the key. You can see the components that represent a stable key here:
https://code.google.com/p/googleappengine/source/browse/trunk/java/src/main/com/google/appengine/api/datastore/Key.java
I cannot find any reference to an Objectify Key.createKey method. Which version of Objectify are you using?
There is however a Key.create(Key<?> parent, java.lang.Class<? extends T> kindClass, java.lang.String name), trying using that and let us know how you get on.
Here is the API page for Key https://objectify-appengine.googlecode.com/svn/trunk/javadoc/com/googlecode/objectify/Key.html

EF4: The closed type 'xxxx' does not have a corresponding element settable property

I'm using this guide to call stored procedure in my projet which using EF4 EDMX through WCFDataservice.
I have mapped a complex type to return items from the stored procedure. If I call the method by http, the XML'result is perfect, but when I call with this code:
public void Test()
{
Uri methodUri = new Uri(entities.BaseUri + "/GetCase");
List<CaseFiltered> result = entities.Execute<CaseFiltered>(methodUri).ToList();
}
I get this exception The closed type CaseFiltered does not have a corresponding element settable property.
I had try this solution but it doesn't work for me.
Have you a solution?
Thank you!
Ok I find the solution according this article
Actually, you did everything
right...However, our client library
does not support materialization of a
collection of complex types directly
(yet). If you look at the output of
the service op, you would see a list
of tag, rather than an Atom
Feed.
My workaround: I'm using Case entities, not the CaseFiltered complex type

dropdown list;servlet Problem

I try to excute the servlet code given, like an exemple to understand how it works.
BUT I did not understand from where the attribut optionDAO and what is the necessity to use it.
The find method seems like the given by hibernate in package".base".
What should I really do to skip this.
Thanks.
It's just a fictive code example according the DAO pattern with a self-explaining classname and methodname which you need to write/implement yourself. E.g.
public class OptionDAO {
public List<Option> find(String dd, String val) {
// Write code here yourself which does the desired task: returning
// a list of options based on the given dropdown id and value.
return options;
}
}
The way how to do it namely differs per environment, ORM libraries used, datamodel design, etc.. that it's impossible to give a concrete code example. Examples how to do it with "plain vanilla" JDBC can be found here. Examples how to do it with Hibernate can be found here. Examlpes how to do it with JPA can be found here.

Resources