Dhaval Goti
Dhaval Goti

Reputation: 457

receiving error "detached entity passed to persist" in spring boot with hibernate while updating row

I have two model class, two repository, two service and two controller which are as below.

    public class ABC {

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

        @Column(name = "abcField1")
        String abcField1;

        @NotNull
        @Email
        @Column(name = "abcField2")
        String abcField2;

        //getter and setters
    }   

    public class XYZ {

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

        @NotNull
        @Column(name = "xyzField1")
        String xyzField1;

        @NotNull
        @Column(name = "xyzField2")
        String xyzField2;

        @ManyToOne(cascade=CascadeType.PERSIST)
        @JoinColumn(name = "abc_id", referencedColumnName = "id")
        ABC abc;

        //getter and setters
    }   

@RestResource(exported = false)
public interface ABCRepository extends CrudRepository<ABC, Long> {

}

@RestResource(exported = false)
public interface XYZRepository extends CrudRepository<XYZ, Long> {

}

@Service
public class XYZService {

    @Autowired
    XYZRepository xyzRepository;

    public XYZ save(XYZ x) {
        return xyzRepository.save(x);
    }
}

@Service
public class ABCService {

    @Autowired
    ABCRepository abcRepository;

    public ABC save(ABC a) {
        return abcRepository.save(a);
    }
}

public class ABCController {

    @Autowired
    ABCService abcService;

    @PostMapping(path = "/abc/save")
    public ResponseEntity<ABC> register(@RequestBody ABC a) {
        return ResponseEntity.ok(abcService.save(a));
    }
}

public class XYZController {

    @Autowired
    XYZService xyzService;

    @PostMapping(path = "/xyz/save")
    public ResponseEntity<XYZ> register(@RequestBody XYZ x) {
        return ResponseEntity.ok(xyzService.save(x));
    }
}

Problem is that when I try to save below JSON it is going insert row in ABC table every time.

{
"xyzField1": "XYZ1", 
"xyzField2": "XYZ2",
"abc":{
    "abcField1": "ABC1",
    "abcField2": "ABC2",
    .
    .
  },
.
.
}

And I want to update row of ABC table instead of adding every time so when I pass id field in below json as shown below then I face error "org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist"

{
"xyzField1": "XYZ1", 
"xyzField2": "XYZ2",
"abc":{
    "id" : "1",
    "abcField1": "ABC1",
    "abcField2": "ABC2",
    .
    .
  },
.
.
}

I have tried to find solution for this and they are suggesting that save method of CrudRepositary will automatically update when we pass id in JSON but it is not working in my case.

Upvotes: 0

Views: 739

Answers (1)

codeLover
codeLover

Reputation: 2592

The issue here seems to be with the cascade type you are providing. Since it is PERSIST, so whenever you try to persist your parent entity (ie XYZ entity), hibernate also tries to persist your child entity(ie ABC entity). Since there is a row already available in ABC with id 1, you are facing this issue.

Therefore, you should change the cascade type to MERGE in order to satisfy both the cases.

Upvotes: 2

Related Questions