Json #JsonIgnore . How to ignore deeper? - java

So, I am making a project that has a class Save which contains List of GameField class. To save "Save" to DB(with Hibernate).
I'm using JSON and it works pretty good, but it is parsing all fields from GameField , which makes Json String about 600 characters long. Beacuse it is so long , I am getting org.hibernate.exception.DataException which says that size of String is too big.
I was trying to increase avalible space in database to properly store that big String but it didn't work.
So i have found #JsonIgnore and #JsonIgnoreProperties annotations to stop Json from parsing few fields. It worked but only for Save class not for GameField.
Is it possible to prevent Json from parsing any fields that i want?
Here is Save class:
public class Save {
private List<GameField> fields;
// getters setters , etc.
}
Game Field:
public class GameField {
#JsonIgnore
private boolean isSet;
private char fieldSign;
#JsonIgnore
private final int numberInArray;
}
Fragment of parsing code:
public String getEncodedSaveInString(Save save) throws JsonProcessingException {
mapper = new ObjectMapper();
return mapper.writeValueAsString(save);
}
Piece of User class
#Entity
public class User {
#Column(name = "Save")
private Save save;
}
Is there a solution?

Okay, so i found a solution. Only thing i needed to do was putting #JsonIgnore annotation above field setter. Placing it above field itself was not working
Working sample of code:
private Foo foo;
#JsonIgnore
public void setfoo(Foo newFoo){ this.foo = newFoo;}
That works fine :)

Related

How to map a List<ObjectDTO> to Entity inside of a Bean with Model Mapper?

I have a 1:N relationship where a Victim might have lots of EmergencyContacts.
I've created a DTO called VictimDTO and inside of it there's a List and I'm using ModelMapper to convert my DTO into an Entity.
When I get rid of the list just for testing purposes, it works fine placing this code snippet inside of the insert "POST" method in the Controller layer in Java:
VictimEntity victimEntity = modelMapper.map(victimDTO, VictimEntity.class);
But now I've placed this List inside of my VictimDTO and I'm getting an Exception when trying to use this code.
My DTO actual code is this one as it follows below:
public class VictimDTO {
private String name;
private int age;
private String email;
private String phone;
private List<ContactDTO> contactDTOList;
//getters and setters
}
How can I use ModelMapper to convert a POJO with a Collection (List) as an instance variable inside into an Entity?
Thank you for your help.
Best regards,
Lucas AbrĂ£o

Jackson json only convert selected fields and methods

With jackson there is a way to ignore some fields using #JsonIgnore. Is there a way to do the opposite, and only show fields with are annotated? I'm working with an external class with a lot of fields and I only want to select a small subset of them. I'm getting tons of recursion problems (using some type of ORM) where object A -> B -> A -> B -> A .... which are not even necessary to export.
You can configure the object mapper to ignore absolutely everything unless specified by JsonProperty,
public class JacksonConfig {
public static ObjectMapper getObjectMapper(){
//The marshaller
ObjectMapper marshaller = new ObjectMapper();
//Make it ignore all fields unless we specify them
marshaller.setVisibility(
new VisibilityChecker.Std(
JsonAutoDetect.Visibility.NONE,
JsonAutoDetect.Visibility.NONE,
JsonAutoDetect.Visibility.NONE,
JsonAutoDetect.Visibility.NONE,
JsonAutoDetect.Visibility.NONE
)
);
//Allow empty objects
marshaller.configure( SerializationFeature.FAIL_ON_EMPTY_BEANS, false );
return marshaller;
}
}
public class MyObject {
private int id;
#JsonProperty
private String name;
private Date date;
//Getters Setters omitted
in this case only name would be serialized.
Sample repo, https://github.com/DarrenForsythe/jackson-ignore-everything
Yes definitely you can; Create a class with only the feilds you need and add the below property in the object mapper and rest is done.
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES to false
You can use #JsonIgnoreProperties(ignoreUnknown=true) on the pojo class so only the fields which are available in the pojo class will be mapped and resf will be left out.
For example
Json data
{
"name":"Abhishek",
"age":30,
"city":"Banglore",
"state":"Karnatak"
}
pojo class
#JsonIgnoreProperties(ignoreUnknown=true)
Class Person{
private int id;
private String name;
private String city;
}
Here state in not present in the Person class so that field won't be mapped

AWS DynamoDBMapper save method keeps throwing `DynamoDBMappingException: not supported; requires #DynamoDBTyped or #DynamoDBTypeConverted`

I followed everything that is outlined here - https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys. But still no luck.
I have a DynamoDB table with a hash key and a sort key.
Here is my entity class RecentlyPlayed.class
#DynamoDBTable(tableName="some-table")
public class RecentlyPlayed {
#Id
private RecentlyPlayedId recentlyPlayedId;
// ----- Constructor methods -----
#DynamoDBHashKey(attributeName="keyA")
// Getter and setter
#DynamoDBRangeKey(attributeName="keyB")
// Getter and setter
}
Here is my key class RecentlyPlayedId.class
public class RecentlyPlayedId implements Serializable {
private static final long serialVersionUID = 1L;
private String keyA;
private String keyB;
public RecentlyPlayedId(String keyA, String keyB) {
this.keyA = keyA;
this.keyB = keyB;
}
#DynamoDBHashKey
// Getter and setter
#DynamoDBRangeKey
// Getter and setter
}
Here is my repository interface RecentlyPlayedRepository
#EnableScan
public interface RecentlyPlayedRepository extends CrudRepository<RecentlyPlayed, RecentlyPlayedId> {
List<RecentlyPlayed> findAllByKeyA(#Param("keyA") String keyA);
// Finding the entry for keyA with highest keyB
RecentlyPlayed findTop1ByKeyAOrderByKeyBDesc(#Param("keyA") String keyA);
}
I am trying to save an object like this
RecentlyPlayed rp = new RecentlyPlayed(...);
dynamoDBMapper.save(rp); // Throws that error
recentlyPlayedRepository.save(rp); // Also throws the same error
I am using Spring v2.0.1.RELEASE. The wiki in the original docs warns about this error and describes what to do to mitigate. I did exactly what they said. But still no luck.
The link to that wiki is here - https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys
DynamoDB only supports primitive data types, it does not know how to convert your complex field (recentlyPlayedId) into a primitive, such as a String.
To show that this is the case, you can add the annotation #DynamoDBIgnore to your recentlyPlayedId attribute like this:
#DynamoDBIgnore
private RecentlyPlayedId recentlyPlayedId;
You also need to remove the #id annotation.
Your save function will then work, but the recentlyPlayedId will not be stored in the item. If you do want to save this field, you need to use the #DynamoDBTypeConverted annotation and write a converter class. The converter class defines how to convert the complex field into a String, and then uncovert the String into the complex field.
Removing getters/setters for the #Id field fixed the problem for me. This is suggested in https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys
not supported; requires #DynamoDBTyped or #DynamoDBTypeConverted",
i was getting this error when i defined model class with field JsonNode,i converted it to MAP<String,String>,now it is working fine

Want to hide some fields of an object that are being mapped to JSON by Jackson

I have a User class that I want to map to JSON using Jackson.
public class User {
private String name;
private int age;
private int securityCode;
// getters and setters
}
I map this to a JSON string using -
User user = getUserFromDatabase();
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
I don't want to map the securityCode variable. Is there any way of configuring the mapper so that it ignores this field?
I know I can write custom data mappers or use the Streaming API but I would like to know if it possible to do it through configuration?
You have two options:
Jackson works on setters-getters of fields. So, you can just remove getter of field which you want to omit in JSON. ( If you don't need getter at other place.)
Or, you can use the #JsonIgnore annotation of Jackson on getter method of that field and you see there in no such key-value pair in resulted JSON.
#JsonIgnore
public int getSecurityCode(){
return securityCode;
}
Adding this here because somebody else may search this again in future, like me. This Answer is an extension to the Accepted Answer
You have two options:
1. Jackson works on setters-getters of fields. So, you can just remove getter of field which you want to omit in JSON. ( If you don't need getter at other place.)
2. Or, you can use the `#JsonIgnore` [annotation of Jackson][1] on getter method of that field and you see there in no such key-value pair in resulted JSON.
#JsonIgnore
public int getSecurityCode(){
return securityCode;
}
Actually, newer version of Jackson added READ_ONLY and WRITE_ONLY annotation arguments for JsonProperty. So you could also do something like this.
#JsonProperty(access = Access.WRITE_ONLY)
private String securityCode;
instead of
#JsonIgnore
public int getSecurityCode(){
return securityCode;
}
you also can gather all properties on an annotation class
#JsonIgnoreProperties( { "applications" })
public MyClass ...
String applications;
If you don't want to put annotations on your Pojos you can also use Genson.
Here is how you can exclude a field with it without any annotations (you can also use annotations if you want, but you have the choice).
Genson genson = new Genson.Builder().exclude("securityCode", User.class).create();
// and then
String json = genson.serialize(user);
Field Level:
public class User {
private String name;
private int age;
#JsonIgnore
private int securityCode;
// getters and setters
}
Class Level:
#JsonIgnoreProperties(value = { "securityCode" })
public class User {
private String name;
private int age;
private int securityCode;
}
if you are using GSON you have to mark the field/member declarations as #Expose and use the GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
Don't forget to mark your sub classes with #Expose otherwise the fields won't show.
I suggest you use this.
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private int securityCode;
This allows you to set the value of securityCode(especially if you use lombok #Setter) and also prevent the field from showing up in the GET request.
I had a similar case where I needed some property to be deserialized (JSON to Object) but not serialized (Object to JSON)
First i went for #JsonIgnore - it did prevent serialization of unwanted property, but failed to de-serialize it too. Trying value attribute didn't help either as it requires some condition.
Finally, working #JsonProperty with access attribute worked like a charm.

Possible to query a database with subclass entity

Ok, lets say I have a model.
#Entity
public class Person extends Model {
public String name;
public String email;
}
Now. I have a couple of transient fields that don't exist in the database, but I need to access them. Basically they are fields for displaying the Person on a web page.
#Entity
public class PersonDisplay extends Person {
#Transient
public String DT_RowClass = "";
#Transient
public String cellColor = "";
}
Is it possible to query the PersonDisplay and get the Person object plus the PersonDisplay default values?
Like this.
PersonDisplay display = PersonDisplay.find("byEmail" , "test#test.com").first();
I'm running into a few errors when I do this.
Let me know if I need to explain this again.
Look up the #PostLoad annotation, which you can use to initialize any transient variables.

Categories

Resources