0

I am learning JPA and I have good knowledge of Java language.

I would like some help trying to figure out when I try to persist a JPA entity GlassFish server throws a NullPointerEception.

The code itself is the following, a web component, a signup.jsp:

<%-- 
    Document   : signup
    Created on : 24-mar-2018, 11:52:38
    Author     : YonePC
--%>

<%@page import="java.util.ArrayList"%>
<%@page import="entities.Likes"%>
<%@page import="java.util.List"%>
<%@page import="entities.Artwork"%>
<%@page import="java.util.Date"%>
<%@page import="SessionBeans.UserFacade"%>
<%@page import="entities.User"%>
<%@page import="javax.script.ScriptEngine"%>
<%@page import="javax.script.ScriptEngineManager"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@include file="../header.jsp" %>

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Registrarse</title>
    </head>
    <body>

        <% 
            if(request.getParameter("username") != null){
                User user = new User();
                UserFacade userFacade = new UserFacade();
                //user.setId(0);
                user.setName(request.getParameter("username"));
                user.setSurname(request.getParameter("surname"));
                user.setEmail(request.getParameter("email"));
                user.setPhone(Integer.parseInt(request.getParameter("phone")));
                user.setAddress(request.getParameter("address"));
                user.setPassword( request.getParameter("password"));
                user.setImageProfile( new byte[1]);
                user.setBirthday( new Date());
                user.setArtworkList(new ArrayList<Artwork>());
                user.setLikesList(new ArrayList<Likes>());
                System.out.println(user.toString());
                userFacade.create(user);
            }

        %>

        <form class="form-horizontal" action='signup.jsp' method="GET">
            <fieldset>
                <div id="legend">
                    <legend class="">Registrarse</legend>
                </div>
                <div class="control-group">
                    <!-- Username -->
                    <label class="control-label" for="username"><i class="fas fa-user"></i>  Nombre</label>
                    <div class="controls">
                        <input type="text" class="form-control" id="username" name="username" placeholder="" class="input-xlarge">
                    </div>
                </div>

                <div class="control-group">
                    <label class="control-label" for="surname">Apellido</label>
                    <div class="controls">
                        <input type="text" class="form-control" id="surname" name="surname" placeholder="" class="input-xlarge">              
                    </div>
                </div>

                <div class="control-group">
                    <!-- E-mail -->
                    <label class="control-label" for="email"><i class="fas fa-envelope-square"></i>  E-mail</label>
                    <div class="controls">
                        <input type="text" class="form-control" id="email" name="email" placeholder="" class="input-xlarge">
                    </div>
                </div>

                <div class="control-group">
                    <label class="control-label" for="phone"><i class="fas fa-phone"></i>  Movil</label>
                    <div class="controls">
                        <input type="text"  class="form-control" id="phone" name="phone" placeholder="" class="input-xlarge">
                    </div>
                </div>

                <div class="control-group">
                    <label class="control-label" for="address"><i class="fas fa-home"></i>  Direccion</label>
                    <div class="controls">
                        <input type="text" class="form-control" id="address" name="address" placeholder="" class="input-xlarge">
                    </div>
                </div>

                <div class="control-group">
                    <!-- Password-->
                    <label class="control-label" for="password"><i class="fas fa-key"></i>  Contraseña</label>
                    <div class="controls">
                        <input type="password" class="form-control" id="password" name="password" placeholder="" class="input-xlarge">
                    </div>
                </div>

                <div class="control-group">
                    <!-- Password -->
                    <label class="control-label" for="password_confirm">Confirmar contraseña</label>
                    <div class="controls">
                        <input type="password" class="form-control" id="password_confirm" name="password_confirm" placeholder="" class="input-xlarge">
                    </div>
                </div>

                <div class="control-group">
                    <!-- Button -->
                    <div class="controls">
                        <button class="btn btn-success" onclick="alert('Te has registrado')">Registrarse</button>
                    </div>
                </div>
            </fieldset>
        </form>
    </body>
</html>

The input we give are the ones written in the form as follows:

enter image description here

Written in the form:

   Nombre: Enoy
    Apellido: Moreno
    E-mail: e@gmail.com
    Movil: 3
    Direccion: Marte
    Contraseña: 3
    Repite contraseña: 3

Defaults:

                user.setImageProfile( new byte[1]);
                user.setBirthday( new Date());
                user.setArtworkList(new ArrayList<Artwork>());
                user.setLikesList(new ArrayList<Likes>());

The exception message given is:

HTTP Status 500 - Internal Server Error

type Exception report

messageInternal Server Error

descriptionThe server encountered an internal error that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: java.lang.NullPointerException

root cause

java.lang.NullPointerException

note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 4.1.1 logs.
GlassFish Server Open Source Edition 4.1.1 

The line being referenced as the root cause is:

protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

I have tried to understand what happens debugging, and we can see that the User java empty object is creted well: enter image description here

Then we can also see it with all properties: enter image description here

And when we go into the create() method of the entityManager we see how in this following code:

HashMap.java

 /**
     * Removes all of the mappings from this map.
     * The map will be empty after this call returns.
     */
    public void clear() {
        Node<K,V>[] tab;
        modCount++;
        if ((tab = table) != null && size > 0) {
            size = 0;
            for (int i = 0; i < tab.length; ++i)
                tab[i] = null;
        }
    }

In particular in the line:

if ((tab = table) != null && size > 0) {

We get a null if we hover on variable table: enter image description here

To fix this issue for myself I have also read:

NullPointerException in JPA

However the previous post's answer stated that we need to add @EJB before instantiating our object which will be persisted to the server be able to inject the EntityManager, and I am currently declaring User as an @Entity bean:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author sldia
 */
@Entity
@Table(name = "users")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
    , @NamedQuery(name = "User.findById", query = "SELECT u FROM User u WHERE u.id = :id")
    , @NamedQuery(name = "User.findByName", query = "SELECT u FROM User u WHERE u.name = :name")
    , @NamedQuery(name = "User.findBySurname", query = "SELECT u FROM User u WHERE u.surname = :surname")
    , @NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email")
    , @NamedQuery(name = "User.findByPassword", query = "SELECT u FROM User u WHERE u.password = :password")
    , @NamedQuery(name = "User.findByPhone", query = "SELECT u FROM User u WHERE u.phone = :phone")
    , @NamedQuery(name = "User.findByCity", query = "SELECT u FROM User u WHERE u.city = :city")
    , @NamedQuery(name = "User.findByAddress", query = "SELECT u FROM User u WHERE u.address = :address")
    , @NamedQuery(name = "User.findByBirthday", query = "SELECT u FROM User u WHERE u.birthday = :birthday")})
public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 20)
    @Column(name = "name")
    private String name;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 40)
    @Column(name = "surname")
    private String surname;
    // @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 30)
    @Column(name = "email")
    private String email;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 20)
    @Column(name = "password")
    private String password;
    @Column(name = "phone")
    private Integer phone;
    @Size(max = 25)
    @Column(name = "city")
    private String city;
    @Size(max = 30)
    @Column(name = "address")
    private String address;
    @Lob
    @Column(name = "image_profile")
    private byte[] imageProfile;
    @Column(name = "birthday")
    @Temporal(TemporalType.DATE)
    private Date birthday;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "authorId")
    private List<Artwork> artworkList;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
    private List<Likes> likesList;

    public User() {
    }

    public User(Integer id) {
        this.id = id;
    }

    public User(Integer id, String name, String surname, String email, String address, String password) {
        this.id = id;
        this.name = name;
        this.surname = surname;
        this.email = email;
        this.password = password;
        this.address = address;
    }

    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 getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getPhone() {
        return phone;
    }

    public void setPhone(Integer phone) {
        this.phone = phone;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public byte[] getImageProfile() {
        return imageProfile;
    }

    public void setImageProfile(byte[] imageProfile) {
        this.imageProfile = imageProfile;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @XmlTransient
    public List<Artwork> getArtworkList() {
        return artworkList;
    }

    public void setArtworkList(List<Artwork> artworkList) {
        this.artworkList = artworkList;
    }

    @XmlTransient
    public List<Likes> getLikesList() {
        return likesList;
    }

    public void setLikesList(List<Likes> likesList) {
        this.likesList = likesList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof User)) {
            return false;
        }
        User other = (User) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "entities.User[ id=" + id + " ]";
    }

}

I have read too: What is a NullPointerException, and how do I fix it?

EntityManager returns NullPointerException when persisting

EDIT: I have created a persistence.xml to connect the database to glassfish:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="com.mda_comparte_war_1.0-SNAPSHOTPU" transaction-type="JTA">
    <jta-data-source>java:app/comparte</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.schema-generation.database.action" value="create"/>
    </properties>
  </persistence-unit>
</persistence>

Then the glassfish-resources.xml is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
    <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="mysql_comparte_rootPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
        <property name="serverName" value="localhost"/>
        <property name="portNumber" value="3306"/>
        <property name="databaseName" value="comparte"/>
        <property name="User" value="root"/>
        <property name="Password" value=""/>
        <property name="URL" value="jdbc:mysql://localhost:3306/comparte?zeroDateTimeBehavior=convertToNull"/>
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    </jdbc-connection-pool>
    <jdbc-resource enabled="true" jndi-name="java:app/comparte" object-type="user" pool-name="mysql_comparte_rootPool"/>
</resources>

I can connect to database from NetBeans an add a register: enter image description here

And when I try to print as a heading the register added to database, the EntityManager is null enter image description here

The code used to iterate throught list:

 <% 
            UserFacade em = new UserFacade();
            List<User> user = em.findAll();
            Iterator i = user.iterator();
            while(i.hasNext()){
                User curretUser = (User) i.next();


        %>

        <h1><%=curretUser.getName()%></h1>

        <% } %>

And the UserFacade used to instantiate the EntityManager is:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package SessionBeans;

import entities.User;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author sldia
 */
@Stateless
public class UserFacade extends AbstractFacade<User> {

    @PersistenceContext(unitName = "com.mda_comparte_war_1.0-SNAPSHOTPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public UserFacade() {
        super(User.class);
    }

}

Could you help me, please? Thank you!!

Yone
  • 2,064
  • 5
  • 25
  • 56
  • 1
    can you sent whole exception trace, that will be helpful to find out exactly where you are getting a null pointer exception – Ravat Tailor Apr 02 '18 at 18:50
  • if you are getting an NPE on a line "getEntityManager().persist(entity);" you should first check that you have an EntityManager returned from the get call. My guess is you are relying on the server to inject it but haven't connected up correctly - but you would need to show that code and setup for us to help. – Chris Apr 02 '18 at 21:37
  • @Chris thank you for your help you are right EntityManager is null I have added code and images to show what I have tried. – Yone Apr 03 '18 at 10:31

0 Answers0