Problem with JPA Hibernate

Asked

Viewed 103 times

1

I have a problem in a system that I am developing using springboot together with JPA Hibernate. I’m not so experienced using them, so forgive me in advance.

Let’s get to the problem: I have 2 tables currently, one with the name Documento and another with the name Bgo. The table Document is the parent table and Bgo the child table, therefore there is a relationship between them of Onetoone where the Document primary key goes to Bgo as a foreign key, AND AT THE SAME TIME, I want that foreign key to be primary, that is, the Bgo table id will be THE SAME ID as the Document table.

For example: I want when I create a new Document along with Bgo in the same request POST, Document id will be something like id_document = 1, and I want Bgo id to be id_document = 1. I literally want Bgo Id to be the Id that comes from the Document table.

It’s gonna be something like that:

Modelo do banco de dados

Remembering that I just want Bgo to have the same document id, Bgo does not have its own id type "id_bgo", Bgo id is literally Document id.

I’ll show you the code:

Parent entity Documento:

package com.testing.testing.models;


import java.sql.Date;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;


@Entity
@Table(name = "DOCUMENT")
public class Document  {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id_document;

private int num_document;

private Date date;

@OneToOne(mappedBy = "document", cascade = CascadeType.ALL)
private Bgo bgo;

public Document() {
}

public Document(Bgo bgo) {
    this.id_document = bgo.getId_document();
    this.bgo = bgo;
}

public Date getDate() {
    return date;
}

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

public Bgo getBgo() {
    return bgo;
}

public void setBgo(Bgo bgo) {
    this.bgo = bgo;
}

public long getId_document() {
    return id_document;
}

public void setId_document(long id_document) {
    this.id_document = id_document;
}

public int getNum_document() {
    return num_document;
}

public void setNum_document(int num_document) {
    this.num_document = num_document;
}


}

Entity filho Bgo:

package com.testing.testing.models;



import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;


@Entity
public class Bgo {


@Id
private long id_document;

private String name_bgo;

private int num_bgo;

@OneToOne
@PrimaryKeyJoinColumn(name = "id_document", referencedColumnName = "id_document")
private Document document;

public Bgo() {
    
}

public Bgo(Document document) {
    this.id_document = document.getId_document();
    this.document = document;
}

public long getId_document() {
    return id_document;
}

public void setId_document(long id_document) {
    this.id_document = id_document;
}

public String getName_bgo() {
    return name_bgo;
}

public void setName_bgo(String name_bgo) {
    this.name_bgo = name_bgo;
}

public int getNum_bgo() {
    return num_bgo;
}

public void setNum_bgo(int num_bgo) {
    this.num_bgo = num_bgo;
}

public Document getDocument() {
    return document;
}

public void setDocument(Document document) {
    this.document = document;
}




}

Notice that I used this "Primarykeyjoincolumn" in the Bgo table, because I had seen in a forum that this was a way to make the table that is receiving the foreign key, at the same time receive as the primary key as well, that is, it will be a primary and foreign key at the same time, as it has in the bank model. But I don’t know if this is the best way to achieve my goal, so any help will be welcome, since I’m not as experienced with JPA Hibernate.

There I have the Document Controller:

package com.testing.testing.controllers;

import java.util.List;

import com.testing.testing.models.Document;
import com.testing.testing.repository.DocumentRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value="/document")
public class DocumentController {

@Autowired
DocumentRepository documentRepository;


@GetMapping
public List<Document> listDocument() {
    return documentRepository.findAll();
}

@PostMapping
public Document createDocument(@RequestBody Document document) {
    return documentRepository.save(document);
}
}

Bgo’s controller:

package com.testing.testing.controllers;

import java.util.List;

import com.testing.testing.models.Bgo;
import com.testing.testing.repository.BgoRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value="/bgo")
public class BgoController {

@Autowired
BgoRepository bgoRepository;

@GetMapping
public List<Bgo> listBgo() {
    return bgoRepository.findAll();
}
} 

Bgo JPA repository:

package com.testing.testing.repository;

import com.testing.testing.models.Bgo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface BgoRepository extends JpaRepository<Bgo, Long> {

}

Of the Document:

package com.testing.testing.repository;

import com.testing.testing.models.Document;

import org.springframework.data.jpa.repository.JpaRepository;

public interface DocumentRepository extends JpaRepository<Document, Long> {

}

The image of the problem:

Imagem da requisição POST

Note that I am creating the 2 entities in a single endpoint, I am passing the document attributes (remembering that the document id is auto incremented), and then I pass the Bgo object and its attributes inside. But if you notice, it didn’t happen what I wanted, the document id is "id_document=1", but the Bgo de is "id_document=0", and I wanted the Bgo id to be just the Document id.

And when I list Bgo, the same thing happens:

inserir a descrição da imagem aqui

Is it possible to do what I am trying to do? If not, there is another way for me to accomplish this. Who can help me I really appreciate, I can’t stand to stay in this for so long.

Thank you in advance!

  • What would that be, Bgo? maybe you can solve with a @Embedded class, or return the id you need to insert into Bgo while with Entitymanager in a manageable way.

  • Your tables are actually under the same name as in the diagram?

  • Yes, they are, is that the code is in English, except that I forgot to change the name of the tables to English in modeling also.

  • But the name doesn’t matter so much now, I’m just completely without knowing what to do to achieve what I want @Jonylima

  • @Andrémartins, could you show me how I would do that? I’m not so experienced in Java

1 answer

1


You can use the JPA @Mapsid annotation to say that the foreign key of one entity is associated as the primary key of another and before entering you will have to set the Document to your bgo.

Bgo:

@PrimaryKeyJoinColumn(name = "id_document", referencedColumnName = "id_document")
@MapsId
@OneToOne
private Document document;

Documentcontroller:

@PostMapping
public Document createDocument(@RequestBody Document document) {
    document.getBgo().setDocument(document);
    return documentRepository.save(document);
}

You can also map your Bgo as follows and you will no longer need to create the id_document field in bgo:

@Entity
public class Bgo implements Serializable {
  private static final long serialVersionUID = 1L;
  private String name_bgo;
  private int num_bgo;

  @Id
  @OneToOne
  @JoinColumn(name = "id_document", referencedColumnName = "id_document")
  private Document document;

  public Bgo() {

  }

  public Bgo(Document document) {
      this.document = document;
  }

  public String getName_bgo() {
      return name_bgo;
  }

  public void setName_bgo(String name_bgo) {
      this.name_bgo = name_bgo;
  }

  public int getNum_bgo() {
      return num_bgo;
  }

  public void setNum_bgo(int num_bgo) {
      this.num_bgo = num_bgo;
  }

  public Document getDocument() {
      return document;
  }

  public void setDocument(Document document) {
      this.document = document;
  }

}
  • You’re the guy! It worked here! I went to the database and saw that the Bgo id is just the Document id! I just had to put a Jsonignore on top of the private Document document, because I was returning the same thing over and over again. Thanks, bro!

  • if you can recommend me good study places for java, I appreciate it very much.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.