在更新行时,在具有休眠状态的春季启动中接收错误"detached entity passed to persist"



我有两个模型类、两个存储库、两个服务和两个控制器,如下所示。

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));
}
}

问题是,当我尝试在JSON下面保存时,它每次都会在ABC表中插入行。

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

我想更新ABC表的行,而不是每次都添加,所以当我在下面的json中传递id字段时,如下所示,我将面临错误"org.springframework.dao.InvalidDataAccessApiUsageException:传递给持久化的分离实体">

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

我试图找到解决方案,他们建议当我们在JSON中传递id时,CrudRepositary的保存方法会自动更新,但在我的情况下不起作用。

这里的问题似乎与您提供的级联类型有关。由于它是PERSIST,因此每当您尝试持久化父实体(即XYZ实体(时,hibernate也会尝试持久化子实体(即ABC实体(。由于ABC中已有一行id为1,因此您正面临此问题。

因此,您应该将级联类型更改为MERGE,以满足这两种情况。

最新更新