09 septiembre, 2020

Crear un CRUD Java Web en NetBeans usando JPA, EJB, JSF y Primefaces

Herramientas

NetBeans IDE 8.0.2

GlassFish Server 4.1


Pasos

1. Creamos la siguiente base de datos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
create database if not exists java19materias;
use java19materias;
 
create table if not exists dbmateria(
  id_materia int not null auto_increment primary key,
    materia varchar(45)
) engine InnoDB;
 
create table if not exists dbmaestro(
  id_maestro int not null auto_increment primary key,
    nombre varchar(45),
    apellido varchar(45)
) engine InnoDB;
 
create table if not exists dbregistro(
  id int not null auto_increment primary key,
    fecha date not null,
    id_materia int not null,
    id_maestro int not null,
    constraint fk_materia foreign key (id_materia) references dbmateria (id_materia) on update cascade on delete cascade,
    constraint fk_maestro foreign key (id_maestro) references dbmaestro (id_maestro) on update cascade on delete cascade
) engine InnoDB;
 
insert into dbmateria (materia) values('Programación');
insert into dbmateria (materia) values('Matematica');
 
insert into dbmaestro (nombre, apellido) values ('José', 'Toro');
insert into dbmaestro (nombre, apellido) values ('Gabriela', 'Farencena');
 
insert into dbregistro (fecha, id_materia, id_maestro)
values ('2020-08-31', 1, 1);
insert into dbregistro (fecha, id_materia, id_maestro)
values ('2020-08-31', 2, 1);


2. Creamos el Pool de Conexiones en el mismo GlassFish

Ir al post

3. Creamos un proyecto web, para ello vamos a la opción File/New/Java Web/Web Application.



Seleccionamos el servidor GlassFish que es en donde tenemos creado el pool de conexiones. (Ir al post para saber como crear un pool de conexiones en el mismo GlassFish)


Agregamos el framework para trabajar con JSF.


Y en componentes agregamos Primefaces (Por defecto no agrega la versión 5 de Primefaces, si queremos utilizar la última versión, debemos descargar el jar para Primefaces 7 y y agregarlo)



4. Creamos una unidad de persistencia

Clic derecho en el proyecto New/Other, en la ventana que aparece debemos buscar la categoría persistence y dentro el tipo archivo Persistence Unit.



Damos en Next y en la opción Data Source seleccionamos el Data Source que creamos en el servidor.


Finalizamos y ya tenemos creado nuestra unidad de persistencia


5. En Source Package creamos los siguientes paquetes


6. Creamos las entidades, para ello, podemos crear las entidades de manera manual creando clase y agregandole las anotaciones de JPA o podemos generar las entidades a partir de una base de datos.


Maestro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package entity;
 
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name = "dbmaestro")
public class Maestro implements Serializable {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id_maestro;
 
    @Column(name = "nombre")
    private String nombre;
 
    @Column(name = "apellido")
    private String apellido;
 
    public int getId_maestro() {
        return id_maestro;
    }
 
    public void setId_maestro(int id_maestro) {
        this.id_maestro = id_maestro;
    }
 
    public String getNombre() {
        return nombre;
    }
 
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
 
    public String getApellido() {
        return apellido;
    }
 
    public void setApellido(String apellido) {
        this.apellido = apellido;
    }
 
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 79 * hash + this.id_maestro;
        return hash;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Maestro other = (Maestro) obj;
        if (this.id_maestro != other.id_maestro) {
            return false;
        }
        return true;
    }
 
    @Override
    public String toString() {
        return "Maestro{" + "id_maestro=" + id_maestro + '}';
    }
 
}

Materia

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package entity;
 
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name = "dbmateria")
public class Materia implements Serializable {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id_materia;
 
    @Column(name = "materia")
    private String materia;
 
    public int getId_materia() {
        return id_materia;
    }
 
    public void setId_materia(int id_materia) {
        this.id_materia = id_materia;
    }
 
    public String getMateria() {
        return materia;
    }
 
    public void setMateria(String materia) {
        this.materia = materia;
    }
 
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 41 * hash + Objects.hashCode(this.id_materia);
        return hash;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Materia other = (Materia) obj;
        if (!Objects.equals(this.id_materia, other.id_materia)) {
            return false;
        }
        return true;
    }
 
    @Override
    public String toString() {
        return "Materia{" + "id_materia=" + id_materia + '}';
    }
 
}

Registro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package entity;
 
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
 
@Entity
@Table(name = "dbregistro")
public class Registro implements Serializable {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
 
    @Temporal(TemporalType.DATE)
    @Column(name = "fecha")
    private Date fecha;
 
    @ManyToOne
    @JoinColumn(name = "id_maestro")
    private Maestro maestro;
 
    @ManyToOne
    @JoinColumn(name = "id_materia")
    private Materia materia;
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public Date getFecha() {
        return fecha;
    }
 
    public void setFecha(Date fecha) {
        this.fecha = fecha;
    }
 
    public Maestro getMaestro() {
        return maestro;
    }
 
    public void setMaestro(Maestro maestro) {
        this.maestro = maestro;
    }
 
    public Materia getMateria() {
        return materia;
    }
 
    public void setMateria(Materia materia) {
        this.materia = materia;
    }
 
    @Override
    public int hashCode() {
        int hash = 3;
        hash = 31 * hash + this.id;
        return hash;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Registro other = (Registro) obj;
        if (this.id != other.id) {
            return false;
        }
        return true;
    }
 
    @Override
    public String toString() {
        return "Registro{" + "id=" + id + '}';
    }
 
}


7. Creamos los EJB, para ello, nos vamos a la carpeta ejb clic derecho New/Other. Buscamos la categoría Persistence y seleccionamos el tipo de archivo Session Bean For Entity Classes.




AbstractFacade

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package ejb;
 
import java.util.List;
import javax.persistence.EntityManager;
 
public abstract class AbstractFacade<T> {
    private Class<T> entityClass;
 
    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }
 
    protected abstract EntityManager getEntityManager();
 
    public void create(T entity) {
        getEntityManager().persist(entity);
    }
 
    public void edit(T entity) {
        getEntityManager().merge(entity);
    }
 
    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }
 
    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }
 
    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }
 
    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0] + 1);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }
 
    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }
     
}

MaestroFacadeLocal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package ejb;
 
import entity.Maestro;
import java.util.List;
import javax.ejb.Local;
 
@Local
public interface MaestroFacadeLocal {
 
    void create(Maestro maestro);
 
    void edit(Maestro maestro);
 
    void remove(Maestro maestro);
 
    Maestro find(Object id);
 
    List<Maestro> findAll();
 
    List<Maestro> findRange(int[] range);
 
    int count();
     
}

MaestroFacade

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package ejb;
 
import entity.Maestro;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
 
@Stateless
public class MaestroFacade extends AbstractFacade<Maestro> implements MaestroFacadeLocal {
    @PersistenceContext(unitName = "Crud_JPA_EJB_JSFPU")
    private EntityManager em;
 
    @Override
    protected EntityManager getEntityManager() {
        return em;
    }
 
    public MaestroFacade() {
        super(Maestro.class);
    }
     
}

MateriaFacadeLocal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package ejb;
 
import entity.Materia;
import java.util.List;
import javax.ejb.Local;
 
@Local
public interface MateriaFacadeLocal {
 
    void create(Materia materia);
 
    void edit(Materia materia);
 
    void remove(Materia materia);
 
    Materia find(Object id);
 
    List<Materia> findAll();
 
    List<Materia> findRange(int[] range);
 
    int count();
     
}

MateriaFacade

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package ejb;
 
import entity.Materia;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
 
@Stateless
public class MateriaFacade extends AbstractFacade<Materia> implements MateriaFacadeLocal {
    @PersistenceContext(unitName = "Crud_JPA_EJB_JSFPU")
    private EntityManager em;
 
    @Override
    protected EntityManager getEntityManager() {
        return em;
    }
 
    public MateriaFacade() {
        super(Materia.class);
    }
     
}

RegistroFacadeLocal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package ejb;
 
import entity.Registro;
import java.util.List;
import javax.ejb.Local;
 
@Local
public interface RegistroFacadeLocal {
 
    void create(Registro registro);
 
    void edit(Registro registro);
 
    void remove(Registro registro);
 
    Registro find(Object id);
 
    List<Registro> findAll();
 
    List<Registro> findRange(int[] range);
 
    int count();
     
}

RegistroFacade

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package ejb;
 
import entity.Registro;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
 
@Stateless
public class RegistroFacade extends AbstractFacade<Registro> implements RegistroFacadeLocal {
    @PersistenceContext(unitName = "Crud_JPA_EJB_JSFPU")
    private EntityManager em;
 
    @Override
    protected EntityManager getEntityManager() {
        return em;
    }
 
    public RegistroFacade() {
        super(Registro.class);
    }
     
}


8. En el paquete controller creamos los ManagedBean, por cada entidad debería haber un Managed Bean.

MaestroBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package controller;
 
import ejb.MaestroFacadeLocal;
import entity.Maestro;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
@ManagedBean
@SessionScoped
public class MaestroBean {
 
    @EJB
    private MaestroFacadeLocal maestroFacade;
    private List<Maestro> maestroList;
    private Maestro maestro;
 
    public List<Maestro> getMaestroList() {
        this.maestroList = maestroFacade.findAll();
        return maestroList;
    }
 
    public void setMaestroList(List<Maestro> maestroList) {
        this.maestroList = maestroList;
    }
 
    public Maestro getMaestro() {
        return maestro;
    }
 
    public void setMaestro(Maestro maestro) {
        this.maestro = maestro;
    }
 
    @PostConstruct
    public void init() {
        this.maestro = new Maestro();
    }
}

MaterialBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package controller;
 
import ejb.MateriaFacadeLocal;
import entity.Materia;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
@ManagedBean
@SessionScoped
public class MateriaBean {
 
    @EJB
    private MateriaFacadeLocal materiaFacade;
    private List<Materia> materiaList;
    private Materia materia;
 
    public List<Materia> getMateriaList() {
        this.materiaList = materiaFacade.findAll();
        return materiaList;
    }
 
    public void setMateriaList(List<Materia> materiaList) {
        this.materiaList = materiaList;
    }
 
    public Materia getMateria() {
        return materia;
    }
 
    public void setMateria(Materia materia) {
        this.materia = materia;
    }
 
    @PostConstruct
    public void init(){
        this.materia = new Materia();
    }
     
}

RegistroBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package controller;
 
import ejb.RegistroFacadeLocal;
import entity.Maestro;
import entity.Materia;
import entity.Registro;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
 
@ManagedBean
@SessionScoped
public class RegistroBean {
 
    @EJB
    private RegistroFacadeLocal registroFacade;
    private List<Registro> registroList;
    private Registro registro;
    private Materia materia;
    private Maestro maestro;
    private String msj;
 
    public List<Registro> getRegistroList() {
        this.registroList = registroFacade.findAll();
        return registroList;
    }
 
    public void setRegistroList(List<Registro> registroList) {
        this.registroList = registroList;
    }
 
    public Registro getRegistro() {
        return registro;
    }
 
    public void setRegistro(Registro registro) {
        this.registro = registro;
    }
 
    public Materia getMateria() {
        return materia;
    }
 
    public void setMateria(Materia materia) {
        this.materia = materia;
    }
 
    public Maestro getMaestro() {
        return maestro;
    }
 
    public void setMaestro(Maestro maestro) {
        this.maestro = maestro;
    }
 
    @PostConstruct
    public void init() {
        this.registro = new Registro();
        this.materia = new Materia();
        this.maestro = new Maestro();
    }
 
    public void guardar() {
        try {
            this.registro.setMaestro(maestro);
            this.registro.setMateria(materia);
            this.msj = "Registro creado correctamente";
            registroFacade.create(registro);
            this.maestro = new Maestro();
            this.materia = new Materia();
            this.registro = new Registro();
        } catch (Exception e) {
            e.printStackTrace();
            this.msj = "Error: " + e.getMessage();
        }
 
        FacesMessage mensaje = new FacesMessage(this.msj);
        FacesContext.getCurrentInstance().addMessage(msj, mensaje);
    }
 
    public void cargarDatos(Registro reg) {
        try {
            this.maestro.setId_maestro(reg.getMaestro().getId_maestro());
            this.materia.setId_materia(reg.getMateria().getId_materia());
            this.registro = reg;
        } catch (Exception e) {
            e.printStackTrace();
            this.msj = "Error: " + e.getMessage();
        }
    }
 
    public void actualizar() {
        try {
            this.registro.setMaestro(maestro);
            this.registro.setMateria(materia);
            this.msj = "Registro actualizado correctamente";
            registroFacade.edit(registro);
            limpiarDatos();
        } catch (Exception e) {
            e.printStackTrace();
            this.msj = "Error: " + e.getMessage();
        }
 
        FacesMessage mensaje = new FacesMessage(this.msj);
        FacesContext.getCurrentInstance().addMessage(msj, mensaje);
    }
 
    public void eliminar(Registro reg) {
        try {
            registroFacade.remove(reg);
            this.msj = "Registro eliminado correctamente";
        } catch (Exception e) {
            e.printStackTrace();
            this.msj = "Error: " + e.getMessage();
        }
    }
 
    public void limpiarDatos() {
        this.maestro = new Maestro();
        this.materia = new Materia();
        this.registro = new Registro();
    }
 
}

 

9. Creamos la vista

index.xhtml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <p:graphicImage library="img" name="logo.png" width="25px"/>
         
        <p:growl id="msj"/>
 
        <h:form id="nuevo">
            <p:fieldset legend="Nuevo" toggleable="true">
                <p:commandButton value="Nuevo" oncomplete="PF('valor').show();"/>
            </p:fieldset>
        </h:form>
        <p:dialog widgetVar="valor" modal="true" showEffect="clip" header="Nuevo registro"  resizable="false">
            <p:ajax event="close" listener="#{registroBean.limpiarDatos()}" update="p" />
            <h:form id="p">
                <p:panelGrid columns="2">
                    <p:outputLabel value="Fecha" />
                    <p:calendar value="#{registroBean.registro.fecha}" required="true"/>
 
                    <p:outputLabel value="Maestro"/>
                    <p:selectOneMenu value="#{registroBean.maestro.id_maestro}">
                        <f:selectItems value="#{maestroBean.maestroList}" var="m" itemValue="#{m.id_maestro}" itemLabel="#{m.nombre}"/>
                    </p:selectOneMenu>
 
                    <p:outputLabel value="Materia"/>
                    <p:selectOneMenu value="#{registroBean.materia.id_materia}">
                        <f:selectItems value="#{materiaBean.materiaList}" var="m" itemValue="#{m.id_materia}" itemLabel="#{m.materia}"/>
                    </p:selectOneMenu>
 
                    <p:commandButton value="Guardar" actionListener="#{registroBean.guardar()}"
                                     update=":datos p :msj" oncomplete="PF('valor').hide();" rendered="#{registroBean.registro.id == 0}"/>
                    <p:commandButton value="Guardar" actionListener="#{registroBean.actualizar()}"
                                     update=":datos p :msj" oncomplete="PF('valor').hide();" rendered="#{registroBean.registro.id != 0}"/>
                </p:panelGrid>
            </h:form>
        </p:dialog>
 
        <h:form id="datos">
            <p:fieldset legend="Datos" toggleable="true">
                <p:dataTable value="#{registroBean.registroList}" var="c">
                    <p:column headerText="Id">
                        <h:outputText value="#{c.id}"/>
                    </p:column>
 
                    <p:column headerText="Fecha">
                        <h:outputText value="#{c.fecha}">
                            <f:convertDateTime pattern="dd/MM/yyyy"/>
                        </h:outputText>
                    </p:column>
 
                    <p:column headerText="Maestro">
                        <h:outputText value="#{c.maestro.nombre}"/>
                    </p:column>
 
                    <p:column headerText="Materia">
                        <h:outputText value="#{c.materia.materia}"/>
                    </p:column>
 
                    <p:column headerText="Opciones">
                        <p:commandButton value="Actualizar" actionListener="#{registroBean.cargarDatos(c)}" update=":p" oncomplete="PF('valor').show();"/>
                        <p:commandButton value="Eliminar" actionListener="#{registroBean.eliminar(c)}" update=":datos :msj"/>
                    </p:column>
                </p:dataTable>
            </p:fieldset>
        </h:form>
 
 
    </h:body>
</html>



No hay comentarios, ¡cuéntame algo!

Me gustaría saber tu opinión. ¡Saludos!