【发布时间】:2026-01-10 02:40:01
【问题描述】:
我正在使用带有 lombok、mapstruct 和 postgresSQL 的 spring。
我在父/子关系的单向@ManyToOne 关系上遇到错误,我的班级客户
这是我的客户端类:
@Getter
@Setter
@Table(name = "client")
public class Client extends AbstractEntity {
private String name;
@ManyToOne(cascade = CascadeType.ALL)
private Address address;
private boolean headOffice;
@ManyToOne(cascade= CascadeType.ALL)
@JoinColumn(name="client_parent_id")
public Client clientParent;
}
这是我的 abstractEntity 来生成 Id 和一些数据:
@MappedSuperclass
@Getter
@Setter
@RequiredArgsConstructor
public class AbstractEntity {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
private String id;
@CreationTimestamp
private Timestamp createdDate;
@UpdateTimestamp
private Timestamp modifiedDate;
}
这是我的客户服务:
@Service
public class ClientService {
private final ClientRepository clientRepository;
private final ClientMapper clientMapper;
ClientService(ClientRepository clientRepository, ClientMapper clientMapper) {
this.clientRepository = clientRepository;
this.clientMapper = clientMapper;
}
Client getClient(String id) throws FunctionalException {
return this.clientRepository.getById(id)
.orElseThrow(
() -> new FunctionalException("Client not found")
);
}
public ClientDto createOrUpdateClient(ClientDto clientDto, String id) throws FunctionalException {
Client client;
if (id == null) {
verifyInExistence(clientDto);
client = this.clientMapper.toEntity(clientDto);
} else {
client = this.getClient(id);
this.clientMapper.updateClientFromDto(clientDto, client);
}
verifyParent(client, clientDto.getClientParentId());
return this.clientMapper.toDto(this.clientRepository.save(client));
}
private void verifyParent(Client client, String parentId) {
if (parentId != null) {
client.setClientParent(this.getClient(parentId));
} else {
client.setClientParent(null);
}
}
private void verifyInExistence(ClientDto clientDto) throws FunctionalException {
clientRepository.findByName(clientDto.getName()).ifPresent(s -> {
throw new FunctionalException(String.format("Client '%s' already exist", clientDto.getName()));
});
}
}
还有我的休息控制器:
@RestController
@RequestMapping(path = "/api/client")
public class ClientResource {
private final ClientService clientService;
ClientResource(ClientService clientService) {
this.clientService = clientService;
}
@PostMapping
ClientDto addClient(@RequestBody ClientDto clientDto) throws FunctionalException {
return this.clientService.createOrUpdateClient(clientDto, null);
}
@PutMapping(path = "/{id}")
ClientDto updateClient(@PathVariable String id, @RequestBody ClientDto clientDto) throws FunctionalException {
return this.clientService.createOrUpdateClient(clientDto, id);
}
}
当我发布一个有父母或没有父母的新客户时,没关系,一切顺利。
但是当我尝试更新(通过在 clientResource 中使用 put)以删除子实体和父实体之间的关系时,我有一个像这样的休眠异常:
HibernateException: identifier of an instance of xxxx.model.Client was altered from 7fa60bf2-e176-4b96-aae4-cbfa6461cb0e to null
我阅读了很多帖子,但我的 ID 生成良好,我只是不明白为什么我不能将 null 设置为 parent 来定义没有父母的孩子。我还尝试将孩子添加为 OneToMany,但不明白这样做的必要性。
非常感谢您的回复! :) 抱歉英语不好。
【问题讨论】: