Prohibit duplicate registration

Hello, guys. I have a program that works with User Registration. In this program I would like to implement a function that prohibits the registration of cpf or email that already exists in the database.

As database I am using PostgreSQL and Java Hibernate. For visual components, I'm using PrimeFaces.

For development I am using eclipse Mars .1

For authentication and authorization, I'm using Spring Security.

I have searched the internet and found several topics related to this subject and had one where the staff indicated to put the cpf and email column as "unique". Thus, the database does not allow you to register duplicate data. I tested and it worked, but the issue is that the system returns error by the eclipse console and simply an error page in the browser. I would like simply the system to show some message like "this cpf already exists in the system". Tab the user to a page full of error codes would be quite unpleasant.

I am posting the codes of the files that I believe have some relation to the processing of the CPF and email field of the user registration screen.

CadastroUsuario.xhtml

<ui:define name="titulo">#{cadastroUsuarioBean.editando ? "Editar Cadastro de Usuário" : "Novo Usuário"}</ui:define>

<ui:define name="corpo">
<f:metadata>
    <o:viewParam name="usuario" value="#{cadastroUsuarioBean.usuario}"/>
    <f:event listener="#{cadastroUsuarioBean.inicializar}" type="preRenderView"/>
</f:metadata>


<h:form>
    <h1>#{cadastroUsuarioBean.editando ? "Editar Cadastro de Usuário" : "Novo Usuário"}</h1>

    <p:messages autoUpdate="true" closable="true"/>

    <p:toolbar style="margin-top: 20px">
        <p:toolbarGroup>
            <p:button value="Novo" outcome="/usuario/CadastroUsuario" disabled ="#{cadastroUsuarioBean.editando}"/>
            <p:commandButton value="Salvar" id="botaoSalvar" action="#{cadastroUsuarioBean.salvar}" update="@form" />
        </p:toolbarGroup>
        <p:toolbarGroup align ="right">
            <p:button value="Pesquisar" outcome="/usuario/PesquisaUsuario"/>
        </p:toolbarGroup>
    </p:toolbar>

    <p:panelGrid columns="2" id="painel" style="width: 100%; margin-top: 20px" 
    columnClasses="rotulo, campo">

        <p:outputLabel value="Nome" for="nome"/>
        <p:inputText id="nome" size="60" maxlength="60"
        value="#{cadastroUsuarioBean.usuario.nome}" required="true" requiredMessage="Informe seu nome" validatorMessage="formato de nome inválido">
        <f:validateRegex pattern="^[A-Za-záàâãéèêíïóôõöúçñÁÀÂÃÉÈÍÏÓÔÕÖÚÇÑ ]+$"/>
        </p:inputText>

        <p:outputLabel value="Senha" for="senha"/>
        <p:password id="senha" size ="10" maxlength="6" required="true" requiredMessage="Informe uma senha" value="#{cadastroUsuarioBean.usuario.senha}" match="senha2" validatorMessage="As senhas informadas não coincidem. Informe-as novamente"/>

        <p:outputLabel value="Verifique sua senha" for="senha"/>
        <p:password id="senha2" size ="10" maxlength="6" required="true" requiredMessage="Confirme sua senha" value="#{cadastroUsuarioBean.usuario.senha}" match="senha2"/>

        <p:outputLabel value="RG" for="rg"/>
        <p:inputText id="rg" size="20" maxlength="20"
            value="#{cadastroUsuarioBean.usuario.rg}" required="true" requiredMessage="Informe o número do seu RG"/>

        <p:outputLabel value="CPF" for="cpf"/>
        <p:inputMask id="cpf" size="14" maxlength="14"
            value="#{cadastroUsuarioBean.usuario.cpf}" mask="999.999.999-99" required="true" requiredMessage="Informe seu CPF"/>

        <p:outputLabel value="Email" for="email"/>
        <p:inputText id="email" size="50" maxlength="50"
            value="#{cadastroUsuarioBean.usuario.email}" required="true" requiredMessage="Informe um email para contato" validatorMessage="formato de email inválido">

        <f:validateRegex
            pattern="^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$" />
        </p:inputText>

        <p:outputLabel value="Telefone para contato" for="telefone"/>
        <p:inputMask id="telefone" size="14" maxlength="14"
            value="#{cadastroUsuarioBean.usuario.telefone}" mask="(99)9999-9999" required="true" requiredMessage="Informe um telefone para contato"/>

        <p:outputLabel value="Celular para contato" for="celular"/>
        <p:inputMask id="celular" size="14" maxlength="14"
            value="#{cadastroUsuarioBean.usuario.celular}" mask="(99)999999999" required="true" requiredMessage="Informe um celular para contato"/>

        <p:outputLabel value="Estado" for="estado"/>
        <p:selectOneMenu id="estado" value="#{cadastroUsuarioBean.estado}" label="Estado" filter="true" 
        filterMatchMode="contains" required="true" requiredMessage="Informe o estado de residência">
        <f:selectItem itemLabel="" noSelectionOption = "true"/>
            <f:selectItems 
                value="#{cadastroUsuarioBean.listEstados}" var="estado"
                itemValue="#{estado}"  itemLabel="#{estado.estado_sigla}" />
            <p:ajax listener="#{cadastroUsuarioBean.carregarCidades}" update="cidade"/>
        </p:selectOneMenu>

        <p:outputLabel value="Cidade" for="cidade"/>
        <p:selectOneMenu id="cidade" value="#{cadastroUsuarioBean.usuario.cidade}" required="true" requiredMessage="Informe a cidade de residência">
            <f:selectItem itemLabel=""/>
            <f:selectItems value="#{cadastroUsuarioBean.listCidades}" var ="cidade"
            itemValue="#{cidade}" itemLabel="#{cidade.cidadeNome}"/>
        </p:selectOneMenu>

        <p:outputLabel value="CEP" for="cep"/>
        <p:inputMask id="cep" size="8" maxlength="8"
            value="#{cadastroUsuarioBean.usuario.cep}" mask="99999-999" required="true" requiredMessage="Informe o CEP de seu endereço"/>

        <p:outputLabel value="Endereço" for="endereco"/>
        <p:inputText id="endereco" size="100" maxlength="100"
            value="#{cadastroUsuarioBean.usuario.endereco}" required="true" requiredMessage="Informe um endereço de correspondência"/>
    </p:panelGrid>



</h:form>
</ui:define>

User.java

package com.sisRastrbov.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@Entity
@SequenceGenerator(name ="usuario_sequence", sequenceName = "usuario_sequence")
@Table(name = "usuario")
public class Usuario implements Serializable{


private static final long serialVersionUID = 1L;

private Long id;
private String nome;
private String senha;
private String status;
private String cpf;
private String rg;
private String email;
private String telefone;
private String celular;
private String endereco;
private Estado estado;
private Cidade cidade;
private String cep;
private List<Grupo> grupos = new ArrayList<>();

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "usuario_sequence")
public Long getId() {
    return id;
}

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

@NotNull
@Column(nullable = false, length = 60)
public String getNome() {
    return nome;
}

public void setNome(String nome) {
    this.nome = nome;
}

@NotNull
@Column(nullable = false, length = 6)
public String getSenha() {
    return senha;
}

public void setSenha(String senha) {
    this.senha = senha;
}

@NotNull
@Column(nullable = false, length = 14, unique=true)
public String getCpf(){
    return cpf;
}

public void setCpf(String cpf){
    this.cpf = cpf;
}

@NotNull
@Column(nullable = false, length = 20)
public String getRg(){
    return rg;
}

public void setRg(String rg){
    this.rg = rg;
}

@NotNull
@Column(nullable = false, length = 50)
public String getEmail(){
    return email;
}

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

@NotNull
@Column(nullable = false, length = 14)
public String getTelefone(){
    return telefone;
}

public void setTelefone(String telefone){
    this.telefone = telefone;
}

@NotNull
@Column(nullable = false, length = 14)
public String getCelular() {
    return celular;
}

public void setCelular(String celular) {
    this.celular = celular;
}

@NotNull
@Column(nullable = false, length = 200)
public String getEndereco(){
    return endereco;
}

public void setEndereco(String endereco){
    this.endereco = endereco;
}

@NotNull
@Column(nullable = false, length = 9)
public String getCep(){
    return cep;
}

public void setCep(String cep){
    this.cep = cep;
}

@ManyToOne
@JoinColumn(name = "estado_sigla")
public Estado getEstado(){
    return estado;
}

public void setEstado(Estado estado){
    this.estado = estado;
}

@ManyToOne
@JoinColumn(name = "cidadeNome")
public Cidade getCidade() {
    return cidade;
}

public void setCidade(Cidade cidade) {
    this.cidade = cidade;
}

@NotNull
@Column(nullable = false, length = 7)
public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Usuario other = (Usuario) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    return true;
}

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "usuario_grupo", joinColumns = @JoinColumn(name="usuario_id"),
        inverseJoinColumns = @JoinColumn(name = "grupo_id"))
public List<Grupo> getGrupos() {
    return grupos;
}

public void setGrupos(List<Grupo> grupos) {
    this.grupos = grupos;
}

}

Userorep.java

package com.sisRastrbov.repository;

import java.io.Serializable;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.sisRastrbov.model.Usuario;
import com.sisRastrbov.repository.filter.UsuarioFilter;
import com.sisRastrbov.util.jsf.FacesUtil;

public class UsuariosRep implements Serializable {

private static final long serialVersionUID = 1L;
@Inject
private EntityManager manager;

public Usuario guardar(Usuario usuario) {
    EntityTransaction trx = manager.getTransaction();

    trx.begin();

    usuario = manager.merge(usuario);

    trx.commit();

    return usuario;
}

/*public Usuario porNome(String nome) 
{
    return manager.find(Usuario.class, nome);
}*/

public Usuario porNome(String nome) {
    Usuario usuario = null;

    try{
    usuario = this.manager.createQuery("from Usuario where lower(nome) = :nome", Usuario.class)
            .setParameter("nome", nome.toLowerCase()).getSingleResult();
    }catch (NoResultException e){
        // Nenhum usuario encontrado com o nome informado.
    }
    return usuario;
}

public Usuario porId(Long id)
{
    return manager.find(Usuario.class, id);
}

public List<Usuario> listaDeUsu() 
{
    return manager.createQuery("from Usuario", Usuario.class).getResultList();
}

public List<Usuario> raizes()
{
    return  manager.createQuery("from Usuario",Usuario.class).getResultList(); 
}

@SuppressWarnings("unchecked")
public List<Usuario> filtrados(UsuarioFilter filtro) {

    Session session = manager.unwrap(Session.class);

    Criteria criteria = session.createCriteria(Usuario.class);

    if (filtro.getNome() != "") 
    {
        System.out.println(filtro.getNome());
        criteria.add(Restrictions.eq("nome", filtro.getNome()));
    }

    if (filtro.getStatus() != null)
    {
        criteria.add(Restrictions.eq("status", filtro.getStatus()));
    }

    // orderBy do SQL
    return criteria.addOrder(Order.asc("id")).list();
}

public void remover(Usuario usuario) {
    this.manager.remove(usuario);
    EntityTransaction trx = manager.getTransaction();
    trx.begin();
    manager.flush();
    trx.commit();
}

public Usuario porEmail(String email) {
    Usuario usuario = null;

    try{
        usuario = this.manager.createQuery("from Usuario where lower(email) = :email", Usuario.class)
                .setParameter("email", email.toLowerCase()).getSingleResult();
    }
    catch (NoResultException e){
        FacesUtil.addErrorMessage("Nenhum usuário encontrado");
    }
    return usuario;
}
}

Web.xml

<?xml version="1.0" encoding="UTF-8" ?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org    /xml/ns/javaee/web-app_3_1.xsd">
<context-param>  
<param-name>primefaces.THEME</param-name>  
<param-value>bootstrap</param-value>  
</context-param>  

Org.springframework.web.context.ContextLoaderListener org.springframework.security.web.session.HttpSessionEventPublisher

<listener>
   <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
<resource-env-ref>
   <resource-env-ref-name>BeanManager</resource-env-ref-name>
   <resource-env-ref-type>
      javax.enterprise.inject.spi.BeanManager
   </resource-env-ref-type>
</resource-env-ref>

<welcome-file-list>
    <welcome-file>Main.xhtml</welcome-file>
</welcome-file-list>

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>

</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

 <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>
</web-app>

Sorry about the Web.xml have gotten kind of weird, but I couldn't tidy up. I believe the Save method of the Userorep.java would be the key to the solution. If any file is missing, please please let me know that I will add immediately.

I am grateful for any feedback or suggestions.

Author: postgisBeginner, 2016-08-24

2 answers

Try creating a constraint on the bank

Below an example with CNPJ in Postgres

CREATE TABLE IF NOT EXISTS empresa (
    id  bigserial not null,
    cnpj varchar(14) not null,
    razao_social varchar(30) not null,        
    email varchar(300) not null,         
    telefone varchar(14),
    cep varchar(8) not null,
    endereco varchar(100) not null,
    numero varchar(5),
    complemento varchar(100),
    cidade varchar(100) not null,
    bairro varchar(100) not null,
    uf varchar(2) not null,
    latitude numeric(19,15),
    longitude numeric(19,15),
    primary key (id)

)  ;

ALTER TABLE IF EXISTS empresa                                                   
    add constraint UK_cnpj unique (cnpj);      
 1
Author: Marcelo, 2016-08-25 12:52:34

If you want to display a user-friendly message, just deal with the bank exception thrown when trying to register a data that breaks a unique constraint. It would look something like this:

public Usuario guardar(Usuario usuario) {
  EntityTransaction trx = manager.getTransaction();

  trx.begin();

  try {
    usuario = manager.merge(usuario);
  } catch (Exception e) {
     throw new MinhaExcecaoDeNegocio(e.getMessage());
  }

  trx.commit();

  return usuario;
}

With catch capturing the exception you can throw a checkable business exception (Myexcecaodenegocio must be implemented by extending Exception) and capture it in your cadastroUsuarioBean, which will add the message to the user in the facesContext. I put as example The Catch of Exception but you could put a more specific exception in catch, which is recommended inclusive. Hope I helped ^ ^

 0
Author: Giuliana Bezerra, 2016-08-29 11:36:16