I am working on spring data couchbase application.In oracle its saving the enum with name but in couchbase its value. I want to save enum name in couchbase instead of its value. But i dont want to change this below existing code.
Is there any way to do that?
And the enum is not a direct field in document. Its a key value in map of other attribute
public enum Foo {
Moon("Night"),
Star("Night"),
Sun("Day");
private String value;
Foo(String value) {
this.value = value;
}
public String getValue() {
return value;
}
#Override
public String toString() {
return this.value;
}
public class Universe{
Map<Foo, <List<List<Cone>>> bar;
}
Couchbase entity class is using
private List<Universe> universe;
Related
I have a class A (listed below) which can have many different types of attributes saved to it. Naturally these attributes can be of different types. Based on the type of attribute I want to apply some validations to it.
What would be the best way of doing it in Micronaut?
Here is an example of what I want to achieve:
public class A {
private String type;
private String value;
// getter/setter omitted…
}
Some example instances of class A:
{type: "type1", value: "examplevalue1"}
{type: "type2", value: "examplevalue2"}
{type: "type2", value: "examplevalue3"}
Then I have some set of validation rules which are relevant to the respective types. Each type (type1, type2, type3) have separate set of validation rules. These rules are not just restricted to String validation but also semantic and business validation.
I would solve this using specific class per type. You can introduce an interface A
interface A {
String getType();
}
and then implement the concrete types.
public class Type1 implements A {
#NotBlank
private String value;
#Override
public String getValue() { return this.value; }
public void setValue(String v) { this.value = v; }
}
public class Type2 implements A {
#YourCustomValidator
private String value;
#Override
public String getValue() { return this.value; }
public void setValue(String v) { this.value = v; }
}
and then implement a custom Jackson Deserializer which is able to build an instance of A by inspecting the JSON string field type.
I don't think that Drools has anything to do with this question.
I have a DynamoDB table in which I have columns. Two of them will always have the same datatype while one column's datatype will vary. How can I unmarshall/marshall it when using DynamoDB. Below is my DTO.
private Integer id;
private String name;
private Object value;
It is not allowing directly to map "value" field and throwing an exception.
Please help me in this regard.
Declare the field as:-
#CustomObjectFormat(separator = " ")
public Object getValue() {
return value;
}
Sample CustomObjectFormat code:-
The below implementation uses toString() to convert everything to String and persist as String data type in DynamoDB database.
#Target({ElementType.METHOD})
#Retention(RetentionPolicy.RUNTIME)
#DynamoDBTypeConverted(converter=CustomObjectFormat.Converter.class)
public #interface CustomObjectFormat {
String separator() default " ";
public static class Converter implements DynamoDBTypeConverter<String, Object> {
private final String separator;
public Converter(final Class<Currency> targetType, final CustomObjectFormat annotation) {
this.separator = annotation.separator();
}
public Converter() {
this.separator = "|";
}
#Override
public String convert(final Object o) {
return o.toString();
}
#Override
public Object unconvert(final String o) {
return o;
}
}
}
Mapper to save:-
DynamoDBMapper will invoke the custom convert and unconvert accordingly for save and retrieval.
dynamoDBMapper.save(accounts);
DynamoDBTypeConverted JavaDoc
I've got the following enum:
public enum NotificationType {
Store("S"),
Employee("E"),
Department("D"),
All("A");
public String value;
NotificationType(String value) {
this.value = value;
}
#Override
public String toString() {
return this.value;
}
#JsonCreator
public static NotificationType fromValue(String value) {
for (NotificationType type : NotificationType.values()) {
if (type.value.equals(value)) {
return type;
}
}
throw new IllegalArgumentException();
}
}
I've created a converter so that when the enum is saved to the database, it persists the value (S, E, D or A) instead of the name. And I can POST json to the controller with the value and it binds to the object correctly.
However, when I render the JSON from a GET it is still displaying the name (Employee, Store, etc) and I would prefer that it still show the value.
Because your toString method returns the value you want to use to represent your enum, you can annotate it with #JsonValue to tell Jackson that the return value represents the value of the enum.
I have a Value class which holds a value:
public class Value {
protected final Object value;
#JsonValue
public Object getValue() {
return value;
}
#JsonCreator
public Value(final Object value) {
this.value = value;
}
}
This Value class is embedded as a field (amongst other fields) in a data class:
class Data {
protected final Value value;
#JsonProperty("value")
public Value getValue() {
return value;
}
...
#JsonCreator
public Data(#JsonProperty("value") final Value value, ...) {
this.value = value;
....
}
}
When the input JSON has null for the value field of a data object (see below for example), Data.value is null. I would like to have Data.value set to new Value(null). In other words, the data object must hold a non-null value object, which holds the null.
{
"value" : null,
...
}
What is the easiest way to achieve this? I could ofcourse alter the constructor of Data, but I am wondering if Jackson could resolve this automatically.
You can write a custom de-serializer and override the getNullValue() method according to your requirements e.g.
public final class InstantiateOnNullDeserializer
extends JsonNodeDeserializer
{
#Override
public JsonNode getNullValue()
{
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.convertValue(new Value(null), JsonNode.class);
return node;
}
}
and register it on the value field of your Data class
class Data {
#JsonDeserialize(using = InstantiateOnNullDeserializer.class)
protected final Value value;
#JsonProperty("value")
public Value getValue() {
return value;
}
#JsonCreator
public Data(Value value) {
this.value = value;
}
}
Note that you need to remove the #JsonProperty("value") to avoid argument type mismatch. By removing JsonProperty annotation you create a so-called "delegate creator",
Jackson will than first bind JSON into type of the argument, and then call a creator
I do not believe that this is possible without creating your own deserializer or modify the constructor (or #JsonCreator).
From a good old thread in the Jackson User Group:
#JsonProperty does not support transformations, since the data binding is based on incremental parsing and does not have access to full tree representation.
So, in order to avoid a custom deserializer I would do something along the lines of:
#JsonCreator
public Data(#JsonProperty("value") final String value) {
this.value = new Value(value);
}
Which is kind of the opposite of what you asked ;)
I have a non-static data which I need to use on conversion. How can I transfer this data into my adapter class? Probably can I use a XmlAdapter in JAXB RI without an empty constructor (and without annotation of course)?
public class VariableAdapter extends XmlAdapter<String, Variable> {
private Map<String, Variable> varMap;
public VariableAdapter(Map<String, Variable> aVarMap) {
varMap = aVarMap;
}
public Variable unmarshal(String aVarName) {
return varMap.get(aVarName);
}
public String marshal(Variable v) {
return v.getName();
}
}
Here is my class, which I need to convert from/into XML
public class Variable {
private String name;
private Object value;
public Value(String aName, Object aValue) {
name = aName;
value = aValue;
}
public String getName() {return name;}
public Object getValue() {return value;}
public void setValue(Object aValue) {value = aValue;}
}
All Variable objects are initialized before XML processing and must be serialized per its name. Variable after unmarshalling can get another value (if its value was changed between serialization/deserialization).
By default JAXB will create a new instance of the XmlAdapter. You can call the setAdapter method on Marshaller/Unmarshaller to specify a stateful one.
For More Information
http://blog.bdoughan.com/2011/09/mixing-nesting-and-references-with.html