0

I am using a @oneToMany - @manyToOne relationship in my entities but once I need to save a register to the @manyToOne side entity I get a 500 http code error. I've been looking for the mistake with no results since I think everything is ok with the code.

My POST request to "Factura".

{
"monto": 1002,
"persona":
    {
        "id": 1,
        "nombre": "Test",
        "apellidoPaterno": "Testing",
        "apellidoMaterno": "Testing",
        "identificacion": "abc"
    }
 }

The response code:

{
"timestamp": "2022-06-20T18:46:44.318+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/factura"
}

And the error in VSC console.

nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: 
detached entity passed to persist: com.test.gt.clientefactura.models.Persona;

Father entity (@oneToMany - Persona).

@Entity
@Table(name = "persona")
public class Persona {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false, name = "persona_id")
    private Long id;
    
    @Column(nullable = false)
    private String nombre;    

    @Column(nullable = false)
    private String apellidoPaterno;    
    
    private String apellidoMaterno;    

    @Column(unique = true, nullable = false)
    private String identificacion;

    @OneToMany(
        fetch = FetchType.LAZY,
        mappedBy = "fkPersonaId",
        cascade = CascadeType.ALL,
        orphanRemoval = true
        )
    private Set<Factura> facturas = new HashSet<>();
. . .
getters and setters

Child entity (@manyToOne - Factura).

@Entity
@Table(name = "factura")
public class Factura {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(unique = true, nullable = false)
 private Long id;

 @CreationTimestamp
 @Temporal(TemporalType.TIMESTAMP)
 private Date fecha;

 private float monto;

 @ManyToOne(cascade = CascadeType.ALL)
 @JoinColumn(name = "fkPersonaId", referencedColumnName = "persona_id")
 private Persona fkPersonaId;
. . .
getters and setters

The repositories:

@Repository
public interface PersonaRepository extends CrudRepository<Persona, Long>{
    public Optional<Persona> findByIdentificacion(String identificacion);
    public long deleteByIdentificacion(String identificacion);
}

@Repository
public interface FacturaRepository extends CrudRepository<Factura, Long>{
    public abstract ArrayList<Factura> findAllByFkPersonaId(Long personaId);
}

The service class of the entity throwing the error (Factura).

@Service
public class Ventas {

  @Autowired
  FacturaRepository facturaRepository;

  public ArrayList<Factura> listFacturas() {
      return (ArrayList<Factura>) facturaRepository.findAll();
  }

  @Transactional
  public Factura storeFactura(Factura factura) {
      return facturaRepository.save(factura);
  }
. . .

And the controller code:

@RestController 
@RequestMapping("/factura")
public class FacturaRestService {
    @Autowired
    private Ventas facturaService;

    @GetMapping
    public ArrayList<Factura> findFacturas() {
        return facturaService.listFacturas();
    }

    @PostMapping
    public Factura addFactura(@RequestBody Factura factura) {
        return facturaService.storeFactura(factura);
    }
. . .

How can I save the register the way I want to? I'd appreciate any help.

Luis Edwards
  • 73
  • 1
  • 8
  • I ran the app with the VSC debugger. The error I copied was from the VSC console. The error basically comes from the "Persona" class which is the father entity of the relation. – Luis Edwards Jun 20 '22 at 19:17

1 Answers1

1

If you are using hibernate, you can use merge instead of save. But if that's not an option, may be below link will help you

PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

PS: I could add comment below your question because of reputation points so posting it as an answer

Shivaji Pote
  • 479
  • 4
  • 6