Hazelcast get operation - java

Get the hazelcast value by key...
IMap<tblHeaders, HazelcastJsonValue> person = hazelcastInstance.getMap("person");
person.put(new tblHeaders("1", "ram", "0001"), new HazelcastJsonValue("{ \"name1\":\"John1\" }"));
person.put(new tblHeaders("1", "vikas", "0002"), new HazelcastJsonValue("{ \"name2\":\"John2\" }"));
person.put(new tblHeaders("1", "datrs", "0003"), new HazelcastJsonValue("{ \"name3\":\"John3\" }"));
Model Class
public class tblHeaders implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String school_id;
private String name;
private String unique_id;
Here How to get the value by passing single key...
example
HazelcastJsonValue json = person.get("school_id='0001'");
System.out.println(json.toString()); //get the value here

A few things here.
The IMap.get() method can only retrieve by a full key value; since you are providing only a partial key the get() method will not match anything.
The IMap.values() method takes a Predicate argument, and is the right method to use when trying to do a query that matches based on the partial content of the key or the full or partial content of the entry's value.
By default, a Predicate is applied against the value, but you can specify that it apply to the key by using the keyword __key (two underscores) in the attribute field of the predicate.
Since the query may (and does) match multiple items, the correct return type is a Collection of HazelcastJsonValue.
Here's the code that will do what you're trying:
Predicate schoolPredicate = Predicates.equal("__key.school_id", "1");
Collection<HazelcastJsonValue> json = person.values(schoolPredicate);
System.out.println(json); //get the value here
Giving the output
[{ "name3":"John3" }, { "name1":"John1" }, { "name2":"John2" }]

Related

Do not show repository output attributes on the basis of runtime requirements

My code:
Controller
#RestController
public class CatalogController {
#Autowired
CatalogService catalogService;
#Autowired
Helper<List<?>> helperList;
#GetMapping("/addresses/{streetCode}")
public ResponseEntity<?> listByStreetCode(
#PathVariable("streetCode") String streetCode, #RequestParam Map<String, String> map) {
String showDoor = map.get("do");
return helperList.evaluateCorrectHttpResponse(
a -> catalogService.listAddressesByStreetCode(streetCode, showDoor ));
}
Service
#Service
public class CatalogService {
#Autowired
VAddressesRepository vAddressesRepository;
public List<VAddresses> listAddressesByStreetCode(String streetCode, String showDoor ) {
// The following repository output should contain every VAddresses attribute or every attribute but 'door', depending on the parameter 'showDoor '
return vAddressesRepository.findByStreetCode(Integer.valueOf(streetCode));
}
Entity
#Entity
#Table(name = "vAddress", schema = "foo")
public class VAddresses {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
String geoid;
String var1;
// other variables
String door;
// getters and setters
}
So, is there a way to skim model attributes based on showDoor value? Bare in mind that I have to operate on the service layer, not on the controller one because it is standardized.
I tried this example https://www.baeldung.com/jackson-serialize-field-custom-criteria. But I've gotten errors stating
"status": 500,
"error": "Internal Server Error",
"message": "Type definition error: [simple type, class foo.models.VAddresses]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot resolve PropertyFilter with id 'showDoorFilter'; no FilterProvider configured (through reference chain: java.util.ArrayList[0])",
even though I defined showDoorFilter in the service layer before invoking Addresses repository.
Should you have examples on how to apply baeldung's code in this case or better suggestions on how to deal with this issue, feel free to write them.
Thank you in advance for your cooperation.
First Method
I suggest that when you get the list of object from repository you can make a list of map, then for each object you can first convert it to a map then just remove the key corresponding to the object that need not be serialized from the corresponding map, it will done for all the object and return the list of map because as we know JsonFormat string is nothing but a combination of key and value pair so just by looking at json output It can't be easily differentiated whether it is an object or map in case like this.
Here you have to change the return type to List of Map
You can convert object to map using jackson ObjectMapper
below is the example
ObjectMapper objectMapper = new ObjectMapper();
UserName obj = new UserName();
obj.setName("mss");
obj.setSkills(Arrays.asList("java","spring"));
Map<String, Object> map = objectMapper.convertValue(obj, Map.class);
System.out.println(map);
Output
{name=mss, skills=[java, spring]}
Second Method
if you think this is too much of a work
then you can first convert the list that you got from repository to jsonArray and then for each jsonObject in the jsonArray remove the corresponding key which matches with the name of the field which you want to be serialized
Edit : sorry, I didn't know that you can only iterate with the for each loop on instances of java.lang.Iterable. JSONArray is not one of them.
so we will use normal variable for loop with the help of length of JSONArray
#Service
public class CatalogService {
#Autowired
VAddressesRepository vAddressesRepository;
public JSONArray listAddressesByStreetCode(String streetCode, String showDoor ) {
// The following repository output should contain every VAddresses attribute or every attribute but 'door', depending on the parameter 'showDoor '
List<VAddresses> lists = vAddressesRepository.findByStreetCode(Integer.valueOf(streetCode));
JSONArray jsonArray = new JSONArray(new ObjectMapper().writeValueAsString(lists));
int n = jsonArray.length();
for(int i = 0; i < n; ++i){
JSONObject jsonObject = (JSONObject)jsonArray.get(i);
jsonObject.remove(showDoor); // removing the key matching with the required field that is to be not serialized, key has to be in string format
jsonArray.put(i , jsonObject);
/* put the updated jsonObject in the index, even through Java is reference type so when you deleted the key
from jsonObject it should be updated in jsonArray index i, but for surety */
}
return jsonArray;
}
let me know it it works or not

Modify a property value in json string

i have a json string like this
{
"code": "200",
"data": "",
"datadetail": null,
"message": "Khách hàng không tồn tại",
"description": "KH_NOTFOUND:"
}
because the value of data property is "" so that the object mapper can't not map that field in to Java POJO, is that anyway to modify the value of data property to specific string like below
{
"code": "200",
"data": "no data",
"datadetail": null,
"message": "Khách hàng không tồn tại",
"description": "KH_NOTFOUND:"
}
here is the error
detail
Can not instantiate value of type [collection type; class java.util.ArrayList, contains [simple type, class vnptpay.collection.adapter.partner.water.laichau.Datum]] from String value (''); no single-String constructor/factory method
here is my target java object class to map
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"code",
"data",
"datadetail",
"message",
"description"
})
#JsonIgnoreProperties(ignoreUnknown = true)
public class GetBillResponse implements Serializable{
#JsonProperty("code")
private String code;
#JsonProperty("data")
private ArrayList<Datum> data = null;
#JsonProperty("datadetail")
private Object datadetail;
#JsonProperty("message")
private String message;
#JsonProperty("description")
private String description;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
here is my mapping code
ObjectMapper mapper = new ObjectMapper();
GetBillResponse obj = null;
obj = mapper.readValue(output.toString(), GetBillResponse.class);
Assuming output.toString() is your JSON string you could add .replace("\"\"", \"{none}\"). Java should be able to interpret this as an ArrayList with one element (maybe my syntax is wrong, but there is definitely a way to initialise an ArraList from a String).
Edit: Now that I think about it, you probably need JSON-syntax, not Java-syntax, so .replace("\"\"", \"[]\") or something like that.
As said in the comments, you're mapping from a wrong type.
In your JSON "data": "" refers to a String field name data. When the java code is mapping it, as the default value passed is a string, it tries to look for an ArrayList constructors that takes a String as you defined it as list in your Java code:
#JsonProperty("data")
private ArrayList<Datum> data = null;
So you have 2 options now:
you send a valid JSON array that will be mapped to the list like "data": []. (assuming you have a constructor like Datum(String value))
You change the data mapping in your java code to a String and map it to an ArrayList later (if for instances your splitting the String on commas or so)
Also for the record I wouldn't advise you yo map data to an ArrayList but rather map it to a List as it is common best practice to refer to interfaces and not implementations !

Storing database entries in an ArrayMap

This is somewhat a 2 question in one. It's for a video game and I am using libgdx, so it must be relatively fast.
I have object that will be read and written to a derby database. Some of those objects data structure will be defined at runtime, so I cannot make a POJO with getters and setters and using the persistance API for example.
Instead a data object will look like this
import java.sql.Types;
import com.badlogic.gdx.utils.Array;
public class Creature extends PBDBsystem_table
{
protected static Array<PBDBsystem_field> s_field_list = new Array<PBDBsystem_field>();
protected static String s_table_name = new String ("creature");
Creature ()
{
create ( s_table_name, s_field_list );
}
public static boolean init()
{
s_field_list.add ( new PBDBsystem_field ("pk", Types.INTEGER, 0, "", true, true ));
s_field_list.add( new PBDBsystem_field ("name", Types.VARCHAR, 30 ));
s_field_list.add( new PBDBsystem_field ("cost", Types.INTEGER, 0, "1" ));
s_field_list.add( new PBDBsystem_field ("strength", Types.INTEGER ));
create_table ( s_table_name, s_field_list);
return true;
}
}
For your information, the full length constructor is defined as:
public PBDBsystem_field ( String name, int type, int size, String default_value, boolean not_null, boolean primary_key )
What this basically do is that init() will create a list of field in an Array that will remain statically in the class and a reference to the table name and field list is passed to the parent class though create(). So that each object has a reference on it's data structure (Which is allocated only once). Then the parent class define the data container for each object like this:
private ArrayMap<String, String> p_data_list; /** structure to contain database data */
Right now I am placing all fields as strings. The key is the field name, and the value is the field data. I am using generic getters and setters in the parent class that require a key like for example:
public void set ( String key, String value)
{
p_data_list.put( key, value);
}
public String get ( String key )
{
return p_data_list.get(key);
}
Question 1: Is it recommended to store everything as string as it will sometimes demand conversion to int which could slow things down. I was thinking of using for example the Interger class instead of primitives and make an array map of Object instead of String. But I should still get conversion and casting issues, but they should remain in the parent class if I do all the generic getters/setter correctly.
Ok, during the creation of the object, I had by reflex created a new string instance for each field in the table like this.
protected void create ( String table_name, Array<PBDBsystem_field> field_list )
{
p_table_name = table_name;
p_field_list = field_list;
p_data_list = new ArrayMap <String, String> ();
p_data_list.ordered = false;
for ( PBDBsystem_field field: p_field_list)
{
p_data_list.put ( field.name, new String() );
}
}
This method reference the table name and field list to the parent class, then for each field it create a new string to contain the data. But if I modify the content of a field using the set method above, it will use another string to insert it in the array map. Which leads me to
Question 2: Will it do a deep copy into the array map's string, or will it simply reference the string that was passed in the set method? Meaning that there is no reason to actually instantiate a string for each field. I should rather leave everything to null.
Considering it's for a video game, I want to minimize the use of the garbage collector by making reusable object or reduce pointless object destruction.

Can not deserialize instance with jackson

I'm working on a RESTful app in which the response is passed as JSON string from Extjs to the java , so I am using the jackson to deserialize into the java POJO.
Below is my request:
{
"filter": "[{"type":"string","value":"sdadsadsa","field":"groupName"}]",
"limit": 10
}
The FilterParams class looks like this:
class FilterParams {
#JsonProperty( value = "type" )
private String type;
/** The value. */
#JsonProperty( value = "value" )
private String value;
/** The group name. */
#JsonProperty( value = "field" )
private String field;
}
For conversion to pojo am using below code
mapper.readValue(json, FilterParams.Class);
But still am getting the "Can not deserialize instance of FilterParams" . How to convert it into the pojo.
Any help would be greatly appreciated. Thanks.
Your JSON is invalid. Value of filter shouldn't start with " if it's a JSON array, or should have escaped inner " if it's a String.
Your FilterParams class does not reflect the data in your JSON at all: it should have a limit int property and an array or a Collection of Filters
Then you should have a Filter class with type, value and field properties
Your JSON contains 2 elements : filter & limits so that Jackson is not able to match this JSON String into a FilterParams object.
To ignore the JSON part that deal with limit, do the following :
JsonNode tree = mapper.readTree(<JSON_STRING>);
FilterParams fp = mapper.treeToValue(tree.get("filter"), FilterParams.class);

Accessing variable in Map<Class, String> by Index

I have a LinkedHashMap with a class as the Key as such:
private final Map<Files, String> list = new LinkedHashMap<Files,String>();
Files is a class consisting of 3 variables:
class Files {
public String file;
public String duration;
public String status;
}
Now I need to access the variables in Files using a index. I know that LinkedHashMap does not allow retrieving values using Index, so I tried this:
List<Entry<Files,String>> randAccess = new ArrayList<Entry<Files,String>>(list.entrySet());
Using randAccess.get(index) I can retrieve the Key itself, but not the specific variables inside the class. So the output is somethinglike Files#6aa91761=String.
I want to be able to get the variable, something like: list.Files.status.Get(index) would return return the value of "status" at the right Index.
You can get the Files variables from the Map.Entry using .getKey(). From there you can get the status field directly.
randAccess.get(index).getKey().status

Categories

Resources