-1

I want to create a java class to handle restful requests under search/* path. Here is my servlet entry in web.xml file:

<servlet>
        <servlet-name>Search-Servlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>gr.histopath.platform.controllers.search</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Search-Servlet</servlet-name>
        <url-pattern>/search/*</url-pattern>
    </servlet-mapping>

My Testing Java Class is:

package gr.histopath.platform.controllers.search;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import gr.histopath.platform.model.TransferObjects.Incident;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.criteria.CriteriaBuilder;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;

@Path("")
public class SearchController {

    private ObjectMapper mapper;
    private String jsonString;
    private List<Incident> incidentsList;
    protected EntityManager entityManager;
    private static EntityManagerFactory factory;
    private CriteriaBuilder criteriaBuilder;

    public SearchController() {

        this.mapper = new ObjectMapper();
        this.jsonString = null;
        this.incidentsList = new ArrayList<Incident>();

        if (factory == null) {
            factory = Persistence.createEntityManagerFactory("PersistenceUnit");
        }

        this.entityManager = factory.createEntityManager();
        this.criteriaBuilder = entityManager.getCriteriaBuilder();

    }

    @POST
    @Path("incidents")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public String searchIncidents(Incident requestBody) {

        System.out.println("POST RECEIVED THE FOLLOWING: ");
        System.out.println(requestBody.toString());

        return "testing";
    }
}

My POJO Incident Object is:

package gr.histopath.platform.model.TransferObjects;

import com.fasterxml.jackson.annotation.JsonManagedReference;

import javax.persistence.*;
import java.sql.Date;

/**
 * Created by mixtou on 7/1/17.
 */
@Entity
public class Incident {
    private int id;
    protected int protocolNo;
    private Date date;
    private byte isPayed;
    private String yliko;
    private String makro;
    private String anoso;
    private String mikro;
    private String symperasma;
    private String klinikesPlirofories;
    private String histo;
    private String simpliromatikiEkthesi;
    private Patient patient;
    private Doctor doctor;
    private Clinic clinic;
    private SigningDoctor signingDoctor;


    @Id
    @Column(name = "id")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "protocolNo")
    public int getProtocolNo() {
        return protocolNo;
    }

    public void setProtocolNo(int protocolNo) {
        this.protocolNo = protocolNo;
    }

    @Basic
    @Column(name = "date")
    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Basic
    @Column(name = "isPayed")
    public byte getIsPayed() {
        return isPayed;
    }

    public void setIsPayed(byte isPayed) {
        this.isPayed = isPayed;
    }


    @Basic
    @Column(name = "yliko")
    public String getYliko() {
        return yliko;
    }

    public void setYliko(String yliko) {
        this.yliko = yliko;
    }

    @Basic
    @Column(name = "makro")
    public String getMakro() {
        return makro;
    }

    public void setMakro(String makro) {
        this.makro = makro;
    }

    @Basic
    @Column(name = "anoso")
    public String getAnoso() {
        return anoso;
    }

    public void setAnoso(String anoso) {
        this.anoso = anoso;
    }

    @Basic
    @Column(name = "mikro")
    public String getMikro() {
        return mikro;
    }

    public void setMikro(String mikro) {
        this.mikro = mikro;
    }

    @Basic
    @Column(name = "symperasma")
    public String getSymperasma() {
        return symperasma;
    }

    public void setSymperasma(String symperasma) {
        this.symperasma = symperasma;
    }

    @Basic
    @Column(name = "klinikesPlirofories")
    public String getKlinikesPlirofories() {
        return klinikesPlirofories;
    }

    public void setKlinikesPlirofories(String klinikesPlirofories) {
        this.klinikesPlirofories = klinikesPlirofories;
    }

    @Basic
    @Column(name = "histo")
    public String getHisto() {
        return histo;
    }

    public void setHisto(String histo) {
        this.histo = histo;
    }

    @Basic
    @Column(name = "simpliromatikiEkthesi")
    public String getSimpliromatikiEkthesi() {
        return simpliromatikiEkthesi;
    }

    public void setSimpliromatikiEkthesi(String simpliromatikiEkthesi) {
        this.simpliromatikiEkthesi = simpliromatikiEkthesi;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Incident incident = (Incident) o;

        if (id != incident.id) return false;
        if (protocolNo != incident.protocolNo) return false;
        if (isPayed != incident.isPayed) return false;
        if (date != null ? !date.equals(incident.date) : incident.date != null) return false;
        if (yliko != null ? !yliko.equals(incident.yliko) : incident.yliko != null) return false;
        if (makro != null ? !makro.equals(incident.makro) : incident.makro != null) return false;
        if (anoso != null ? !anoso.equals(incident.anoso) : incident.anoso != null) return false;
        if (mikro != null ? !mikro.equals(incident.mikro) : incident.mikro != null) return false;
        if (symperasma != null ? !symperasma.equals(incident.symperasma) : incident.symperasma != null) return false;
        if (klinikesPlirofories != null ? !klinikesPlirofories.equals(incident.klinikesPlirofories) : incident.klinikesPlirofories != null)
            return false;
        if (histo != null ? !histo.equals(incident.histo) : incident.histo != null) return false;
        if (simpliromatikiEkthesi != null ? !simpliromatikiEkthesi.equals(incident.simpliromatikiEkthesi) : incident.simpliromatikiEkthesi != null)
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = (int) (id ^ (id >>> 32));
        result = 31 * result + protocolNo;
        result = 31 * result + (date != null ? date.hashCode() : 0);
        result = 31 * result + (int) isPayed;
        result = 31 * result + (yliko != null ? yliko.hashCode() : 0);
        result = 31 * result + (makro != null ? makro.hashCode() : 0);
        result = 31 * result + (anoso != null ? anoso.hashCode() : 0);
        result = 31 * result + (mikro != null ? mikro.hashCode() : 0);
        result = 31 * result + (symperasma != null ? symperasma.hashCode() : 0);
        result = 31 * result + (klinikesPlirofories != null ? klinikesPlirofories.hashCode() : 0);
        result = 31 * result + (histo != null ? histo.hashCode() : 0);
        result = 31 * result + (simpliromatikiEkthesi != null ? simpliromatikiEkthesi.hashCode() : 0);
        return result;
    }

    @ManyToOne
    @JoinColumn(name = "patient_id", referencedColumnName = "id", nullable = false)
    @JsonManagedReference
    public Patient getPatient() {
        return patient;
    }

    public void setPatient(Patient patient) {
        this.patient = patient;
    }

    @ManyToOne
    @JoinColumn(name = "doctor_id", referencedColumnName = "id", nullable = false)
    @JsonManagedReference
    public Doctor getDoctor() {
        return doctor;
    }

    public void setDoctor(Doctor doctor) {
        this.doctor = doctor;
    }

    @ManyToOne
    @JsonManagedReference
    @JoinColumn(name = "clinic_id", referencedColumnName = "id")
    public Clinic getClinic() {
        return clinic;
    }

    public void setClinic(Clinic clinic) {
        this.clinic = clinic;
    }

    @ManyToOne
    @JsonManagedReference
    @JoinColumn(name = "signingDoctor_id", referencedColumnName = "id", nullable = false)
    public SigningDoctor getSigningDoctor() {
        return signingDoctor;
    }

    public void setSigningDoctor(SigningDoctor signingDoctor) {
        this.signingDoctor = signingDoctor;
    }
}

If i send to servlet a completely empty JSON object {} using POST it works. If i send any JSON Object without date field it works. If i send however a JSON object with empty date {..., "date":"", ...} i get Java Null Pointer Exception Error. If is send a JSON Object with some date {..., "date": "2000-10-10", ...} it works. Dots notation {...} means anything

Any Ideas why is this happening and how to solve it?? I use a search Form, and i send the entire Form as an Object Using Angular's form.value where if i don't set anythind on date it sends {"date":""} which causes the null pointer exception error on java back-end

mixtou
  • 729
  • 10
  • 27
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Kenster Mar 23 '18 at 11:54

3 Answers3

1

The solution is what @Sathishkumar Manogaran posted in his 2nd comment. I changed java.sql.Date to java.util.Date in my Incident POJO class and it magically worked. So it was the imported library that caused the problem.

mixtou
  • 729
  • 10
  • 27
0

You have to send null value instead of empty string. Send "date": null

Yacata
  • 1
  • And it won't complain about Null Pointer Exception If i send NULL?? This is not easy because i will have to change the way angular creates/implements *form.value*. Isn't there a way to handle it with java on the back-end?? – mixtou Mar 23 '18 at 11:38
  • Probably you will have to modify the type of date parameter from Date to String and make some conversions if you don't want to modify angular. – Yacata Mar 23 '18 at 11:50
0

You can allow Date as null value while populating this particular POJO. And this available in javax.persistance.* package itself.

@Column(name = "date", nullable = true)
public Date getDate() {
    return date;
}

You can use same nullable = false for some mandatory field too.

Note: But this is not the good practice to do.

Satz
  • 307
  • 3
  • 19
  • This is not working, I get exactly the same behavior Null Pointer Exception. – mixtou Mar 23 '18 at 12:39
  • Could you share stacktrace so I can understand exactly in which line u r getting NPException..? – Satz Mar 23 '18 at 13:34
  • Can you try to use java.util.Date instead of java.sql.Date? Just try this once, if you are able to receive Incident JSON properly then you have to create separate Incident POJO class and IncidentEntity class. :) – Satz Mar 23 '18 at 15:29
  • Yes with java.util.Date it works. That was great. Thanks a lot. You saved me and my time. Thanks again – mixtou Mar 23 '18 at 15:34
  • Let me reproduce the same in my workspace and let you know.. Until Hodor :) – Satz Mar 23 '18 at 15:37