#JsonProperty annotation is getting ignored in mongodb collection - mongodb

As I'm new to springboot and mongodb I've used https://start.spring.io/ and generated a demo project with following settings.
Then created a model as below:
package com.example.model;
import java.io.Serializable;
import java.time.LocalDate;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.mongodb.core.mapping.Document;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#Getter
#Setter
#ToString
#Configuration
#Document(collection = "customer")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Customer implements Serializable {
private static final long serialVersionUID = 6748432793461621268L;
#JsonProperty("customer_id")
private String customerId;
#JsonProperty(value= "external_customer_reference_id")
private String externalCustomerReferenceId;
#JsonProperty("title")
private String title;
#JsonProperty("first_name")
private String firstName;
#JsonProperty("middle_name")
private String middleName;
#JsonProperty("last_name")
private String lastName;
#JsonProperty("email")
private String email;
#JsonProperty("phone")
private String phone;
#JsonProperty("note")
private String note;
#JsonProperty("date_of_birth")
private String dateOfBirth;
#JsonProperty("sex")
private String sex;
#JsonProperty("contact_address")
private Address address;
#CreatedDate
#JsonProperty("create_timestamp")
private LocalDate createdDate;
#LastModifiedDate
#JsonProperty("modified_timestamp")
private LocalDate modifiedDate;
}
I'm able to save customer in mongodb collection customer. But the collection attribute names are not as same as #JsonProperty("modified_timestamp").
Why db collection attribute names are not as same as JsonProperty? How do I get db collection attribute names as same as JsonProperty?

In MongoDB you're saving an object with his properties names.
JsonProperty annotation mapping the deserialization and the serialization with given object.
Marker annotation that can be used to define a non-static method as a
"setter" or "getter" for a logical property (depending on its
signature), or non-static object field to be used (serialized,
deserialized) as a logical property. Default value ("") indicates that
the field name is used as the property name without any modifications,
but it can be specified to non-empty value to specify different name.
Property name refers to name used externally, as the field name in
JSON objects.
https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonProperty.html
By using #Field property annotation you can save property in different name as in object.

Related

Auto generated String type #Id in Spring Boot to connect mongo

I am incrementing my Autogenerated Id value but I need String type
.This is my service class:
package com.stackroute.orderhistory.service;
import com.stackroute.orderhistory.model.AutogenerateId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import java.util.Objects;
import static org.springframework.data.mongodb.core.FindAndModifyOptions.options;
#Service
public class SequenceGeneratorService {
#Autowired
private MongoOperations mongoOperations;
public String getSequenceNumber(String sequenceName){
Query query=new Query(Criteria.where("order_id").is(sequenceName));
Update update=new Update().inc("seq",1);
AutogenerateId counter = mongoOperations
.findAndModify(query,
update, options().returnNew(true).upsert(true),
AutogenerateId.class);
return !Objects.isNull(counter) ? counter.getSeq() : "1";
}
}
.This is my Entity Class :
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
#NoArgsConstructor
#ToString
#AllArgsConstructor
#Getter
#Setter
#Document(collection = "orders")
public class OrderHistoryModel {
#Transient
public static final String SEQUENCE_NAME="Ordersequence";
#Id
private String orderId;
private String productName;
private int orderAmount;
private String orderPlaced;
private String orderStatus;
private String paymentMethod;
private String shippingAddress;
}
.This is my AutoGenerated Entity class :
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "db_sequence")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class AutogenerateId {
#Id
private String id;
private String seq;
}
In this Code I am getting Order_Id as 1,2,3 and so on (In Postman)
But I need Order_Id like order1, order2, order3 and so on...
Please help me out.
In my case, I didn't customise the auto-generation of the id, instead:
in my entity i just annotated the id by #Id s follow:
the DTO:
and here's my service :
the method dtoToUser:
and mongodb will generate a random and unique UUID for me, as follow:
So, Use IDs provided by MongoDB, which are more or less universally unique

ebean query 2 models and render to html

I have setup 2 models in ebean, both work fine when queried separately. Now i need to get into my Show.scala.html fields from both my product & heading models, the product fields work fine but I also need the DateOrder from heading, but I am getting a compilation error of value DateOrder is not a member of object models.Heading, please help
My Models
package models;
import io.ebean.Finder;
import io.ebean.Model;
import play.data.validation.Constraints;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
#Entity
#Table(name="Heading")
public class Heading extends Model {
#Id
#Column(name="JobKeyID")
public Integer JobKeyID;
#Constraints.MaxLength(50)
#Constraints.Required
#Column(name="Name")
public String Name;
#Column (name="JobNumber", columnDefinition = "NVARCHAR")
public String JobNumber;
#Constraints.Required
#Column(name="SellingPriceIncTax")
public Integer SellingPriceIncTax;
#Constraints.Required
#Column(name="DateOrder")
public Date DateOrder;
#Column(name="CustomerID")
public Integer CustomerID;
#OneToMany(mappedBy = "heading", fetch = FetchType.EAGER)
public List<Product> product;
public static Finder<Integer, Heading> find = new Finder<>(Heading.class);
}
package models;
import io.ebean.Finder;
import io.ebean.Model;
import io.ebeaninternal.server.type.ScalarTypeJsonList;
import play.data.validation.Constraints;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
#Entity
#Table(name="Product")
public class Product extends Model {
#Id
#Column(name = "ItemKeyID")
public Integer ItemKeyID;
#Constraints.MaxLength(50)
#Constraints.Required
#Column(name = "ProductName")
public String ProductName;
#Column(name = "ItemNumber")
public Integer ItemNumber;
#Constraints.Required
#Column(name = "DesignName")
public String DesignName;
#Column(name = "JobKeyID")
public Integer JobKeyID;
#ManyToOne
#JoinColumn(name="JobKeyID")
public Heading heading;
#OneToMany(mappedBy = "product")
public List<Information> information;
public static Finder<Integer, Product> find = new Finder<>(Product.class);
}
My Controller
public Result show(Integer id){
List<Product> products = Ebean.find(Product.class)
.fetch("heading")
.where().eq("JobKeyID",id)
.setFirstRow(0)
.setMaxRows(10)
.findList();
return ok(show.render(products)) ;
}
and my scala.html
#(products : List[Product])
#Layout("All Books") {
<h1> All Books</h1>
#for(product <- products) {
<a class="btn btn-link" href="#routes.BooksController.specinfo(product.JobKeyID, product.ItemKeyID)">#product.ProductName</a>
<p> Design Name : #product.DesignName</p>
<p> Order Date : #Heading.DateOrder</p>
<img src ="#routes.ImagesController.getImage("419326-1.svg")"/>
}
}
You're trying to get field DateOrder via class, but it's not a static member. I believe it's the cause. If I understood your intention correctly, you should replace #Heading.DateOrder with #product.heading.DateOrder.

FindBy method returnign all records in PagingAndSortingRepository

Im using a findBy method in a interface that extends PagingAndSortingRepository. This method is:
public List<MyType> findByClassification(String classification);
When I invoke this method (myObject.findByClassification("A")), it returns all values and not only records filtered by classification "A".
The class model:
package mypackage;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "mytype")
public class MyType implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Integer id;
private String name;
private String classification;
//getters and setters
}
Other find methods work fine:
findByClassificationAndName_StartingWith
findByName
These methods return only filtered records and not all records in table.
Any idea?
Thanks!

Play Framework: Inheritance sort by type

In my Application, I have 2 Classes:
- Group
- Model
and one base class Element.
I use the single table strategy to persist these models. (strategy = InheritanceType.SINGLE_TABLE). Thus a column dtypeis created in my table.
I'm now trying to sort my pages based on this type:
find.where().disjunction()
.add(Expr.ilike("name", "%" + filter + "%"))
.orderBy("dtype asc, name asc," + sortBy + " " + order).findList()
But this throws an Exception, that dtype cannot be found.
How can I sort based on the type?
Thanks!
Sample base model can look like:
package models.db;
import play.db.ebean.Model;
import javax.persistence.*;
import java.util.Date;
#Entity
#Table(name = "content")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "dtype", discriminatorType = DiscriminatorType.STRING)
#DiscriminatorValue("content")
public abstract class Content extends Model {
#Id
public Long id;
#Column(name = "dtype", insertable = false, updatable = false)
public String dtype;
public static Finder<Long, Content> find = new Finder<>(Long.class, Content.class);
public String title;
public Date created = new Date();
public Date modified = new Date();
}
Then you can extend it like:
package models.db;
import javax.persistence.*;
#Entity
#DiscriminatorValue("news")
public class News extends Content {
#Id
public Long id;
public static Finder<Long, News> find = new Finder<>(Long.class, News.class);
public String newsSource;
}
or
package models.db;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Date;
#Entity
#DiscriminatorValue("post")
public class Post extends Content {
#Id
public Long id;
public static Finder<Long, Post> find = new Finder<>(Long.class, Post.class);
public Date publishDate;
}
So you can choose all contents via:
List<Content> contents = Content.find.where().orderBy("dtype ASC").findList();
Of course these objects will have only shared fields: id, dtype, title, created and modified, for getting i.e. (News) newsSource or (Post) publishDate you need to get these objects with their own finders i.e. using id value from general Content query.

assign timestamp in jpa annotation

is there a way to automatically assing a timestamp value in a Date variable on a enity EJB?
here is how my enity looks like.
package com.jr.entities;
import java.util.Date;
import javax.persistence.Column;
public class TransactionDAO {
private String uid;
private ProductDAO product;
#Column(name="date")
private Date date;
private String customerId;
}
i could not find any examples how this is done or does this have to be done programatically?
What do you mean, have an initial value for new objects?
Just initialize it in the object's constructor, or in the field def.