How can I set a custom name for #JsonProperty? - java

I have got a problem with setting a custom name for #JsonProperty, I use mustache to generate classes form openapi.yaml and make a library to use it in different projects.
Here is a sample of yaml:
PriceType:
type: object
properties:
ID:
type: string
And I get the next:
#JsonProperty("ID")
private String ID;
public PriceType ID(String ID) {
this.ID = ID;
return this;
}
But I need:
#JsonProperty("user_id")
private String ID;
public PriceType ID(String ID) {
this.ID = ID;
return this;
}
I suspect it can be because of my mustche file defenition for the property:
#JsonProperty("{{baseName}}")
but I dont know how to make it, at the same time I have to do it just for this particular scenario, which means basename in my mustache stays and other classes are generated normally
I have tried to change my mustache file, but crashed it. And tried to somehow set jsonproperty name in yaml but i don't know how.

Related

Morphia: Saving document in a specific collection

I am using Morphia 2.x, and I have a usecase where i want to save 1 Entity class into 2 different Collections.
However Morphia 2.x save method doesn't have any option to pass a Collection Name, Where as Morphia 1.x had this option.
I am not sure why they have removed this option.
#Entity
public class Unit {
#Id
private String id;
protected Unit() {
}
public String getId() {
return this.id;
}
public void setId(final String id) {
this.id = id;
}
}
Morphia 2.3 will reintroduce this functionality as an option passed via the alternateCollection option on InsertOneOptions (among other options classes). I'm working to get this out soon.

How to Specify Accepted API Params in Spring Data Neo4j?

I am trying to understand how spring data converts my POJO to the API params/body and return type. My goal is to have a save endpoint that takes in non generated fields only, but returns all fields. As an example, consider the following class:
#Node
public class Person {
#Id #GeneratedValue(generatorClass = UUIDStringGenerator.class) private String id;
private String firstname, lastname;
private String zip;
}
with acommpanying repository
public interface PersonRepository extends CrudRepository<Person, String> {}
I don't need the POST /persons endpoint to accept id or zip, only firstName and lastName. However I would like it to return all fields on a successful save.
The first thing I noticed is that if I:
Add getters, but not setters for id and zip and
Add getters and setters for firstName and lastName
The generated open api docs request body has this format
{
"id": "string",
"firstname": "string",
"lastname": "string",
"zip": "string"
}
and if i set id or zip in the request, it will somehow set the properties in the DB, despite both fields being private and having no setters. How is this possible?
I came up with this solution, which works, but it is reliant on id and zip being included in the constructor args but intentionally being ignored in the method body.
#Node
#Setter
#Getter
public class Person {
#Id #GeneratedValue(generatorClass = UUIDStringGenerator.class) private String id;
private String firstname, lastname;
private String zip;
Person(String id, String firstname, String lastname, String zip) {
// If I uncomment the below line, it will override the id with the one passed in.
// this.id = id;
this.firstname = firstname;
this.lastname = lastname;
}
}
This solution works because of the object population hierarchy, it will default to using my all args constructor. But it is not ideal because:
I could easily make a mistake and allow end users to set a custom id.
The API docs request body still asks for id and zip, but setting them now just does nothing
The lack of a no args constructor means the find method fails to cast the result back into a Person object
What is the recommended way to have my api only accept a subset of fields on create, ignoring those that I do not supply when writing to the data store, and then return a different subset of fields as the response. Are projections the recommended way to handle custom responses on default CrudRepository methods?
NB: I am aware that I need to use config.exposeIdsFor(Person.class); and am doing so. I am also awa

How do I use DynamoDBAutoGeneratedKey to give me an auto generated key?

I need to use DynamoDBAutoGeneratedKey from the AWS SDK to give me a random key(of type String) that I can then use to do something. I can't find any examples online of doing this, and while it seems like it should be relatively straightforward I am really struggling to get this working. Can anyone link me to an example of this being used?
Found easy answer.
String uniqueID = UUID.randomUUID().toString();
Screw using DynamoDBAutoGeneratedKey, sounds like a headache.
#DynamoDBTable( tableName = "Details")
public class Details
{
#DynamoDBGeneratedUuid( DynamoDBAutoGenerateStrategy.CREATE )
private UUID id;
....
#DynamoDBHashKey(attributeName = "id")
#DynamoDBAutoGeneratedKey
public UUID getId()
{
return id;
}
// also you need to add the setter otherwise you will get an exception
public void setId(UUID id)
{
this.id = id;
}
...

Generating UUID based #ID for Playframework 2.3x

Good day Guys,
I want to create Models that don't use the default #Id auto generation for Playframework and Ebeans. I have seen online that there are options for Using GenericModel, however that class doesn't seem to be included in version 2.3x. I have done this in order to workaround it but i still fall short my aim
public class ProductVariants extends Model
{
#Id
String id;
public String getId() {
return (this.id == null) ? UUID.randomUUID().toString() : this.id;
}
public void setId(String id) {
this.id = id;
}
}
The issue with this is that i have to manually set the ID before i can save the object e.g.
productVariant.setId(productVariant.getId());
productVariant.save();
Both for a primary model and all it related models with a OneToMany relationship, and it is currently giving me issues when i bind from the view to the Model object with error ERROR executing DML bindLog[] error[Field 'id' doesn't have a default value]]].
Please any help will be appreciated.
Good day Guys,
I finally fixed this by using the UUID class that ships with the JDK. So when you are creating your Models you create them with the
#Id
public java.util.UUID id
Also in the routes file if you need to map to a record by the ID you can do that by doing something like this
GET /:pid/edit controllers.Application.edit(pid: java.util.UUID)

How to change a field name in JSON using Jackson

I'm using jackson to convert an object of mine to json.
The object has 2 fields:
#Entity
public class City {
#id
Long id;
String name;
public String getName() { return name; }
public void setName(String name){ this.name = name; }
public Long getId() { return id; }
public void setName(Long id){ this.id = id; }
}
Since I want to use this with the jQuery auto complete feature I want 'id' to appear as 'value' in the json and 'name' to appear as 'label'. The documentation of jackson is not clear on this and I've tried every annotation that even remotely seems like it does what I need but I can't get name to appear as label and id to appear as value in the json.
Does anyone know how to do this or if this is possible?
Have you tried using #JsonProperty?
#Entity
public class City {
#id
Long id;
String name;
#JsonProperty("label")
public String getName() { return name; }
public void setName(String name){ this.name = name; }
#JsonProperty("value")
public Long getId() { return id; }
public void setId(Long id){ this.id = id; }
}
Be aware that there is org.codehaus.jackson.annotate.JsonProperty in Jackson 1.x and com.fasterxml.jackson.annotation.JsonProperty in Jackson 2.x. Check which ObjectMapper you are using (from which version), and make sure you use the proper annotation.
Jackson
If you are using Jackson, then you can use the #JsonProperty annotation to customize the name of a given JSON property.
Therefore, you just have to annotate the entity fields with the #JsonProperty annotation and provide a custom JSON property name, like this:
#Entity
public class City {
#Id
#JsonProperty("value")
private Long id;
#JsonProperty("label")
private String name;
//Getters and setters omitted for brevity
}
JavaEE or JakartaEE JSON-B
JSON-B is the standard binding layer for converting Java objects to and from JSON. If you are using JSON-B, then you can override the JSON property name via the #JsonbProperty annotation:
#Entity
public class City {
#Id
#JsonbProperty("value")
private Long id;
#JsonbProperty("label")
private String name;
//Getters and setters omitted for brevity
}
There is one more option to rename field:
Jackson MixIns.
Useful if you deal with third party classes, which you are not able to annotate, or you just do not want to pollute the class with Jackson specific annotations.
The Jackson documentation for Mixins is outdated, so this example can provide more clarity. In essence: you create mixin class which does the serialization in the way you want. Then register it to the ObjectMapper:
objectMapper.addMixIn(ThirdParty.class, MyMixIn.class);

Categories