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.