How to remove empty object in which all the fields are null and those fields are removed by using " #JsonInclude(Include.NON_NULL) "? - spring

I am using this #JsonInclude(Include.NON_NULL) to remove null fields from the Objects. It is working as expected. Let's see with an example .
If I have an object like this -
User{id=null,name=null}
(user object which has all of its fields as null value).
In the response it is coming like ----
{
user:{}
}
This is the thing I need to remove. Either I should assign null or remove the entire property.
Thanks for the help !.

To meet your requirement we need to use #JsonSerialize annotation with User field. Here is the working code.
#Getter
#Setter
public class Demo implements Serializable{
#JsonSerialize(using = CustomJsonSerializer.class)
private User user;
}
#Getter
#JsonInclude(JsonInclude.Include.NON_NULL)
public class User implements Serializable{
private Integer id;
private String name;
public User() {
}
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
}
public class CustomJsonSerializer extends JsonSerializer<User> {
#Override
public void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (user.getId() == null && user.getName() == null) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeStartObject();
jsonGenerator.writeNumberField("id", user.getId());
jsonGenerator.writeStringField("name", user.getName());
jsonGenerator.writeEndObject();
}
}
}
if User{id=null,name=null} then response will be
{
"user":null
}
Reference - https://www.sghill.net/2012/how-do-i-write-a-jackson-json-serializer-deserializer/

Related

Getting null values with data in list of collection of object

I am trying to add few employee objects inside the list named collectionofEmployees here.I am able to add the data but i am getting first record for custom object attributes as nulls.The data is getting inserted after that properly.
Here is my controller.
#RestController
public class CustomController {
#Autowired
Employees collectionofEmployees;
#RequestMapping("/add")
public Employees add() {
collectionofEmployees.add(new Employee(1,"XYZ"));
collectionofEmployees.add(new Employee(3, "VTY"));
return collectionofEmployees;
}
Here is my Employees Model class which contains list of employee
#Component
public class Employees {
#Autowired
private List<Employee>employees;
public List<Employee> getEmployees() {
return employees;
}
public Employees(List<Employee> employees) {
super();
this.employees = employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public void add(Employee employee)
{
this.employees.add(employee);
}
Here is my employee class
#Component
public class Employee {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public Employee() {
super();
}
public Employee(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
The output i am getting is as {"employees":[{"id":null,"name":null},{"id":1,"name":"XYZ"},{"id":3,"name":"VTY"}]}
Help would be appreciated alot:)I want to avoid nulls
Try to remove #Component from Employee class. It is initialized by Spring and injected to your
#Autowired
private List<Employee>employees
As i still dont know how to avoid nulls at time of intialisation done by spring,for temporary purpose i have added collectionofEmployees.getEmployees().remove(0) under add method which removes the nulls from the input.

Spring boot application I can not get data from oracle database it returns [] in postman

Spring boot application I can not get data from oracle database it returns []. In postman, it returns other requests e.g home method in controller class returns correctly. also, the table created by model class the problem is getting data from the table.
Here is the postman result:
I get this in console:
Model class
#Entity // This tells Hibernate to make a table out of this class
public class Userr {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
//Controller Class
#RestController
public class MainController {
#Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
#PostMapping(path="/add") // Map ONLY POST Requests
public #ResponseBody String addNewUser (#RequestParam String name
, #RequestParam String email) {
// #ResponseBody means the returned String is the response, not a view name
// #RequestParam means it is a parameter from the GET or POST request
Userr n = new Userr();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
#GetMapping(path="/all")
public #ResponseBody Iterable<Userr> getAllUsers() {
// This returns a JSON or XML with the users
//
return userRepository.findAll();
}
#GetMapping(path="/al")
public List<Userr> printPersonInfo() {
List<Userr> list = new ArrayList<>();
userRepository.findAll().forEach(list::add);
return list;
}
#RequestMapping("/user")
public String home(){
return "PPPPPP";
}
}
//Repository Class
public interface UserRepository extends CrudRepository<Userr, Integer> {
}
Add #Repository annotation to your UserRepository. It will help with your issue.

null values inserted while auditing

My AuditListener
public class EmployeeAuditListeners {
#PrePersist
public void prePersist(Employee employee){
perform(employee,Action.INSERTED);
}
#PreUpdate
public void preUpdate(Employee employee){
perform(employee,Action.UPDATED);
}
#PreRemove
public void preRemove(Employee employee){
perform(employee,Action.DELETED);
}
#Transactional
public void perform(Employee emp, Action action){
EntityManager em = BeanUtil.getBean(EntityManager.class);
CommonLogs commonLogs = new CommonLogs();
commonLogs.setQuery("new query");
em.persist(commonLogs);
}
}
and My Auditable.class
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class Auditable<U> {
#CreatedBy
protected U createdBy;
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
protected Date createdDate;
#LastModifiedBy
protected U lastModifiedBy;
#LastModifiedDate
#Temporal(TemporalType.TIMESTAMP)
protected Date lastModifiedDate;
}
My CommonLogs.class
#Entity
#EntityListeners(AuditingEntityListener.class)
public class CommonLogs extends Auditable<String> {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String query;
public CommonLogs() {
}
public CommonLogs(String query) {
this.query = query;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
}
My Employee.java class
#Entity
#EntityListeners(EmployeeAuditListeners.class)
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String address;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
and I have a simple Rest Controller
#RestController
#RequestMapping("/api")
public class EmployeeController {
#Autowired
private EmployeeRepository employeeRepository;
#PostMapping("/employees")
public Employee createEmployee(#RequestBody Employee employee){
return employeeRepository.save(employee);
}
}
I want to log it on my table (common_logs) every time i perform some crud operations on my Employee Entity.
the above given example is working to some extent as it successfully stores employee and invokes EmployeeAuditListeners.
but now while saving CommongLog entity i expect it's parent class Auditable to automatically insert createdBy, createdDate etc. for now only query and id is inserted on common_logs table and remaining columns are null.
You can review the documentation for Auditing in here.
To enable the automatic Auditing, you must add the annotation #EnableJpaAuditing in your Application class:
#SpringBootApplication
#EnableJpaAuditing
class Application {
static void main(String[] args) {
SpringApplication.run(Application.class, args)
}
}
If you want the fields #CreatedBy and #LastModifiedBy too, you will also need to implement the AuditorAware<T> interface. For example:
class SpringSecurityAuditorAware implements AuditorAware<User> {
public User getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return null;
}
return ((MyUserDetails) authentication.getPrincipal()).getUser();
}
}

Sprint Date Rest successful, but no data

Entity
#Data
#Accessors(chain = true, fluent = true)
#Entity
#Table(name = "T_NOTE")
#Access(AccessType.FIELD)
public class Note implements Serializable
{
#Id
#GeneratedValue
private Long id;
private Date date;
#Column(length = 2000)
private String content;
private String title;
private String weather;
}
Repository
#RepositoryRestResource(collectionResourceRel = "note", path = "note")
public interface NoteRepository extends AbstractRepository<Note, Long>
{
}
GET http://localhost:8080/note/2
{
"_links": {
"self": {
"href": "http://localhost:8080/note/2"
}
}
}
No entity field data, why?
EIDT
After I add standard setter/getter, everything is ok now.
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public Date getDate()
{
return date;
}
public void setDate(Date date)
{
this.date = date;
}
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content = content;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getWeather()
{
return weather;
}
public void setWeather(String weather)
{
this.weather = weather;
}
Is this cause by jackson mapper ? How can I use fluent API with this ?Why not just use reflection to generate JSON ?
EDIT
What I need is this configuration
#Configuration
#Import(RepositoryRestMvcConfiguration.class)
public class ShoweaRestMvcConfiguration extends RepositoryRestMvcConfiguration
{
#Override
protected void configureJacksonObjectMapper(ObjectMapper mapper)
{
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
}
}
Caused by this
#Accessors is probably stepping over the #Data annotation, and with fluent = true it generates getters with the same name as the field, like id() and date() (#Accessor documentation). That's why Spring doesn't see any of the fields.
I think you can safely remove both #Accessors and #Access, since #Access's takes the default value from id (if you annotated the field, it will be FIELD, if you annotated the getter, it will be PROPERTY).

How to update entity using spring-data neo4j

My problem is when I'm trying to update entity using GraphRepository 'save' method, all my fields, that was not changed, are being rewritten with null values.
I make PUT request with only id and name, because I want change User's name, but save method automatically changes password field to null value. I wanna update only dirty values. How can I achieve this? Maybe there is some kind of merge or update methods?
My entity class looks like this:
#NodeEntity
public class User {
#GraphId Long id;
String name;
String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#JsonIgnore
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
My repository class looks like this:
public interface UserRepository extends GraphRepository<User> {
public User findById(Long id);
}
#Transactional
public void update(Long id, String name) {
User user = repository.findById(id);
if (user != null) {
user.setName(name);
}
}

Resources