我有两个模型类,两个存储库,两个服务和两个控制器,如下所示 .
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:传递给persist的分离实体”
{
"xyzField1": "XYZ1",
"xyzField2": "XYZ2",
"abc":{
"id" : "1",
"abcField1": "ABC1",
"abcField2": "ABC2",
.
.
},
.
.
}
我试图为此找到解决方案,他们建议我们在JSON中传递id时会自动更新CrudRepositary的save方法但是在我的情况下它不起作用 .
2 回答
您收到此错误是因为,hibernate尝试使用
@Id
注释插入您自己的id,但它在您的json中找到id,因此它认为此实体是一个分离的实体 .所以让hibernate插入id而不是你传递它 .
这里的问题似乎与您提供的 cascade type 有关 . 因为它是
PERSIST
,所以每当你试图坚持你的父实体(即XYZ实体)时,hibernate也会尝试持久化你的子实体(即 ABC 实体) . 由于ABC中已有一行ID为1,因此您将遇到此问题 .因此,您应该将级联类型更改为
MERGE
以满足这两种情况 .