With MongoTemplate, I'm having trouble with the find method when using what I'm calling a Parameterized Type of an Object. I might not be accurate in how to describe this so I will give an example:
public class Animal<T> {
private String name
private T attributes
}
public class Dog {
private Integer weight
...
}
So I have those stored in Mongo like:
{
"name": "Bernese Mountain Dog"
"attributes": {
"weight": 100
}
}
If it was stored as a Dog document, I would be able to do something like:
mongoTemplate.find(query, Dog.class)
And then get a List<Dog> returned. But if my return type is something like List<Animal<T>>, then if I try to do something like:
mongoTemplate.find(query, Animal.class)
that will give an error about not being able to convert it. This also is not possible code:
mongoTemplate.find(query, Animal<Dog>.class)
because that's just bad syntax.
Thoughts?
What I finally found that works was:
mongoTemplate.find(query, (Class<Animal<T>>)(Class<T>) Animal.class);
It seems pretty wonky, but it worked. I do get warnings about the unchecked cast which I'm unable to sort out without suppressing them. If anyone has a better solution, please let me know.
Related
How looks my json:
event object
{
...
"game": {
//game fields
}
}
...
}
I am trying to do:
event.setGame(new Game());
And check if there is my value by mockMvc
.andExpect(jsonPath("$.game").value(event.getGame()))
But i am getting error:
java.lang.AssertionError: JSON path "$.game"
Expected : Event(id= null, name= null, ...)
Actual :null
Why i am getting null, if i should get just empty game?
P.S. even if i set fields to game, i will get null
I make .andDo(print), and get :
Body = // event
{
"id":"5f087eec-8bf0-11eb-8dcd-0242ac130003",
"game":
{
"id":null,
"team1":null,
"team2":null,
"gameDate":null,
},
"user":
{
//user fields
}
}
How looks controller:
#GetMapping("/{id}")
public ResponseEntity<GetEventById> getEventById #PathVariable("id") String id) {
GetEventByIResponse dto= service.getEventById(id);
return ResponseEntity
.status(HttpStatus.OK)
.body(dto);
}
In my test i am creating GetEventByIResponse, how it looks:
public class Event {
private String id;
private Game game;
...
}
The JsonPath assert works as follows:
It first parses the path result into a Map/List/Object, to see if the origin was an array/object/simple type.
Then, if it's a Map (like in your case) it tries to parse the path result into the same type as the expected object.
Finally it compare the created object to the expected object using equals().
In your case I see several problems:
The AssertionError talks about an Event although you seem to hand in a Game.
We do not know if the serialization/deserialization works at all
Maybe you should try one of the following:
Place a breakpoint right here to watch the assert steps in your debugger:
Start with simple type comparisons:
.andExpect(jsonPath("$.id").value("foo"))
.andExpect(jsonPath("$.game.id").value("bar"))
Seems like the json path referencing the game child object is incorrect, try below:
.andExpect(jsonPath("$.event.game").value(event.getGame()))
I want to create a class with a public enum (to be used by other modules) with an internal String raw value (I don't want other modules to read the raw Value, but I do want to read it internally inside the same module).
I know I can just create another private function that receives the enum and returns a String but I want to avoid that.
I think it's not possible, I tried doing like this first:
public enum Emotion {
case Hate = EmotionInner.Hate, Love = EmotionInner.Love
}
internal enum EmotionInner: String {
case Hate = "hate", Love = "love"
}
But it won't compile.
Your enums at least should be the same type - so if you want to has rawValue() it will has it in both enum. And you can't make rawValue() smth like final or static.
By the way, maybe it's not bad way to make a function for it?
So I'm attempting to go through a groovyObject's fields and obtain the property of that field. So this is what I got(sorry its a little rough so cleaning would be appreciated but not necessary, I'm also doing a little debugging and other stuff with the Log and what not.):
public void traverse(final GroovyObject groovy) throws RepositoryException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
{
Field[] theFields = groovy.getClass().getDeclaredFields();
final ArrayList<Field> fields = new ArrayList<Field>();
int count =0;
for(Field field : theFields)
{
fields.add(field);
LOG.error("{} = {}",field.getName(), groovy.getProperty(field.getName()));
}
//this is the guava tree traverser
TreeTraverser<GroovyObject> traverser = new TreeTraverser<GroovyObject>()
{
#Override
public Iterable<GroovyObject> children(GroovyObject root)
{
return (Iterable<GroovyObject>)root.getProperty(fields.get(0).getName());
//|-->Here I get the String cannot be cast to Iterable. Which I find odd since it is still an object just getProperty takes a string. right?
}
};
Thoughts on this? Thanks for the help!
GroovyObject.getProperty(String) retrieves the value of the given property. And if that value happens to be a String you cannot cast it to Iterable.
If you adjust your log statement, you can inspect the types of the fields:
LOG.error("{} of type {} = {}", field.getName(), field.getType(), groovy.getProperty(field.getName()));
So I figured it outl. Essentially what needs to happen is I need to make two iterators: one for the groovy objects and one for the property strings so the end goal looks like
groovyObject.iterate().next().getProperty(string.iterate().next());
Or something like that, I will update this when I figure it out.!
Once I make that I can go back in and think about making it more efficient
I was reading a book about Linq, and saw that the Distinct method has an overload that takes a comparer. This would be a good solution to a problem I have where I want to get the distinct entities from a collection, but want the comparison to be on the entity ID, even if the other properties are different.
According to the book, if I have a Gribulator entity, I should be able to create a comparer like this...
private class GribulatorComparer : IComparer<Gribulator> {
public int Compare(Gribulator g1, Gribulator g2) {
return g1.ID.CompareTo(g2.ID);
}
}
...and then use it like this...
List<Gribulator> distinctGribulators
= myGribulators.Distinct(new GribulatorComparer()).ToList();
However, this gives the following compiler errors...
'System.Collections.Generic.List' does not contain a definition for 'Distinct' and the best extension method overload 'System.Linq.Enumerable.Distinct(System.Collections.Generic.IEnumerable, System.Collections.Generic.IEqualityComparer)' has some invalid arguments
Argument 2: cannot convert from 'LinqPlayground.Program.GribulatorComparer' to 'System.Collections.Generic.IEqualityComparer'
I've searched around a bit, and have seen plenty of examples that use code like this, but no complaints about compiler errors.
What am I doing wrong? Also, is this the best way of doing this? I want a one-off solution here, so don't want to start changing the code for the entity itself. I want the entity to remain as normal, but just in this one place, compare by ID only.
Thanks for any help.
You're implementing your comparer as an IComparer<T>, the LINQ method overload requires an implementation of IEqualityComparer:
private class GribulatorComparer : IEqualityComparer<Gribulator> {
public bool Equals(Gribulator g1, Gribulator g2) {
return g1.ID == g2.ID;
}
}
edit:
For clarification, the IComparer interface can be used for sorting, as that's basically what the Compare() method does.
Like this:
items.OrderBy(x => new ItemComparer());
private class ItemComparer : IComparer<Item>
{
public int Compare(Item x, Item y)
{
return x.Id.CompareTo(y.Id)
}
}
Which will sort your collection using that comparer, however LINQ provides a way to do that for simple fields (like an int Id).
items.OrderBy(x => x.Id);
I am new to linq and linq2SQL. I have done my homework, i.e. found many results and answers that target similar problems. Seemingly lacking deeper understanding of linq and linq2SQL I am at my wits end.
I have a web application with a simple html and js frontend. I exchange data with my aspx via ajax xmlhttprequests. All the data naturally comes in and is supposed to go out as strings.
What I am trying to do:
private DateTime _date;
[Column(Storage = "_date", Name = "date", DbType = "date", CanBeNull = false)]
public string date
{
get { return this._date.ToString("yyyy-MM-dd"); }
set { this._date = DateTime.ParseExact(value, "yyyy-MM-dd", null); }
}
Instead of converting the string to a datetime in my aspx I would like to just pass on the strings and do the conversion at get and set. Running this code gives me an "invalid cast" error.
Am I trying to do something that is by desing simply not supposed to be done? Is my approach wrong? I don't expect someone else to write the code for me. I don't mind digging in the references, but I don't know where to start. So if someone where to point me in the right direction, I would greatly appreciate it.
Whatever the cast problem is, it is not in the code you are showing.
Converting to and from a DateTime value in a getter/setter is a perfectly reasonable thing to do. The only thing that could happen in your scenario is that you get a FormatException "String was not recognized as a valid DateTime." if the passed in value doesn't match a valid time string in your format - you currently do not handle this.
Solution for now:
[Column(Name = "date", DbType = "date", CanBeNull = false)]
public string date { get; set; }
Apperently linq or "whoever" is responsible can figure the casting out on it's own, if you let it. Right now that's good enough for me.
I have the feeling I will run into simliar casting problems later on and that different solutions may be required. If so I will update this thread.