4

I'm trying to relate two tables

User and Address A user has a single address, an address belongs to only one user. Keys are listed by the ID of an Address so I create my address first and then I create a user and link it with an address id But I can't do it at all, I have the following error in return:

Error creating bean with name 'entityManagerFactory' defined in class path resource [org / springframework / boot / autoconfigure / orm / jpa / HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NullPointerException: Cannot invoke "org.hibernate.mapping.PersistentClass.getTable ()" because "classMapping" is null

i'm totally new to hibernate but i need this project for college so forgive me for the ignorance on the subject

Thats my code:

USER/USUARIO Class:

import org.hibernate.validator.constraints.br.CPF;

import javax.persistence.*;
import javax.validation.constraints.*;


public class Usuario{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column
    @NotNull
    @Size(min = 5,max = 30)
    @Pattern(regexp = "^[a-zA-Z\s]*$", message = "Nome inválido! Digite apenas letras e espaçamento") //Permite apenas letras e espaço
    private String nome;

    @NotNull
    @CPF
    private String cpf;

    @NotNull
    @Email
    private String email;

    @NotNull
    @Size(min = 5,max = 12)
    private String senha;

    private Integer telefone;

    @DecimalMin("0")
    @DecimalMax("5")
    private Double avaliacao;

    @NotNull
    @OneToOne(cascade = CascadeType.ALL,mappedBy = "id")
    private Endereco endereco;

    //Atributos para usuários autônomos

    private Boolean isAutonomo;

    private String categoriaAutonomo;

    private Double precoAutonomo;

//Getters and Setters

ADRESS/ENDERECO Class

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Entity
@Table(name = "endereco")
public class Endereco {

    @Id
    @OneToOne
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @NotNull
    @Size(min = 8,max = 8)
    private String cep;

    @NotNull
    private String bairro;

    @NotNull
    private String logradouro;

    @NotNull
    private Integer numeroLogradouro;

    private String complemento;

    @NotNull
    @Size(min = 2,max = 2)
    private String uf;

    @NotNull
    private String cidade;

CONTROLLER

import br.com.bandtec.projetocaputeam.dominio.*;
import br.com.bandtec.projetocaputeam.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/caputeam")
public class CaputeamController {

    @Autowired
    private UsuariosRepository usuariosRepository;

    @Autowired
    private EnderecoRepository enderecoRepository;

//--- USERS
    @GetMapping("/usuarios")
    public ResponseEntity getUsuarios(){
        List<Usuario> usuarios = usuariosRepository.findAll();
        return !usuarios.isEmpty() ? ResponseEntity.status(200).body(usuarios) :
                                     ResponseEntity.status(204).build();
    }

    @PostMapping("/cadastrar-usuario")
    public ResponseEntity cadastrarUsuario(@RequestBody @Valid Usuario novoUsuario){
        usuariosRepository.save(novoUsuario);
        return ResponseEntity.ok().build();
    }

//--- ADRESS
    @PostMapping("/cadastrar-endereco")
    public ResponseEntity cadastrarEndereco(@RequestBody @Valid Endereco novoEndereco){
        enderecoRepository.save(novoEndereco);
        return ResponseEntity.ok().build();
    }
}

APPLICATION

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProjetoCaputeamApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProjetoCaputeamApplication.class, args);
    }

}

And thats my Logic Model enter image description here

EDIT I tried to delete the "mapped by" part and remove the @OneToOne from Address but now it returns the following error when I try to send an POST of Adress:

org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKMXNOON0IKGA83W1A203Y6OFPN: PUBLIC.ENDERECO FOREIGN KEY(ID) REFERENCES PUBLIC.USUARIO(ID) (1)"; SQL statement:
insert into endereco (bairro, cep, cidade, complemento, logradouro, numero_logradouro, uf, id) values (?, ?, ?, ?, ?, ?, ?, ?) [23506-200]

as if he didn’t enter any Address fields

Im sending my POST by Postman like this:

{
    "bairro": "Vila Prmavera",
    "cep": "03388110",
    "cidade": "São Paulo",
    "complemento": "b1",
    "logradouro": "Rua das dores",
    "numeroLogradouro": 7,
    "uf": "SP"
}
Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
BaaDe
  • 77
  • 1
  • 9

1 Answers1

5

Don't map on the Id. Map means entity mapping not id mapping.

public class Endereco {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @OneToOne
    private Usuario usuario

     ....
   }

Or if you don't want Endereco to hold a reference to a Usuario just remove it. But you can't place @OneToOne on the id field. If you have only on one side the @OneToOne then you need also the annotation @MapsId.

public class Usario {

        @NotNull
        @MapsId
        @OneToOne(cascade = CascadeType.ALL)
        private Endereco endereco;

 public class Endereco {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer id

       }

Because @OneToOne tries to Map with an entity which means to a table in Database. For id there isn't any entity or Table in the database. That is why it complains

Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
  • I think that makes sense, but how can I signal that the User Address attribute should get the address ID? I tried to delete the mapped by part and remove the OneToOne from Address but now it returns the following error: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKMXNOON0IKGA83W1A203Y6OFPN: PUBLIC.ENDERECO FOREIGN KEY(ID) REFERENCES PUBLIC.USUARIO(ID) (1)"; SQL statement: insert into endereco (bairro, cep, cidade, complemento, logradouro, numero_logradouro, uf, id) values (?, ?, ?, ?, ?, ?, ?, ?) [23506-200] – BaaDe Mar 29 '21 at 18:33
  • do you have a h2 database stored in a file? – Panagiotis Bougioukos Mar 29 '21 at 18:39
  • I am using the h2 console but I didn't save it to a local file – BaaDe Mar 29 '21 at 18:46
  • @BeatrizBarbosa check my updated answer. If you have only one side `OneToOne` then you also need `@MapsId` – Panagiotis Bougioukos Mar 29 '21 at 19:02
  • it returned NULL not allowed for column "ENDERECO_ID"; SQL statement: insert into endereco (bairro, cep, cidade, complemento, logradouro, numero_logradouro, uf, id) values (?, ?, ?, ?, ?, ?, ?, ?) [23502-200] As if I sent an empty post – BaaDe Mar 29 '21 at 19:17
  • yea because you have ` @NotNull @OneToOne(cascade = CascadeType.ALL) private Endereco endereco;` – Panagiotis Bougioukos Mar 29 '21 at 19:23
  • You must either send to your request the nested Endereco or remove the `@NotNull` from that field – Panagiotis Bougioukos Mar 29 '21 at 19:24
  • You make a post request with only a Usario that does not contain an Endereco so it complains because it expects NotNull – Panagiotis Bougioukos Mar 29 '21 at 19:25
  • Sorry, I didnt understand I forgot to say that I tested without @NotNull private Endereco endereco and gave this error too but if I sent a post only from address and not from user just wanted to create an address shouldn't it not be dependent on it? Because address has no dependent fields – BaaDe Mar 29 '21 at 19:35
  • now you have another problem. check this answer here https://stackoverflow.com/a/39094773/7237884 – Panagiotis Bougioukos Mar 29 '21 at 20:01