【发布时间】:2021-08-27 08:02:07
【问题描述】:
我在尝试使用 JPA 更新对象时遇到问题。问题不是更新现有对象,而是创建新对象以及新的嵌入数据。
这是我的java代码:
第一个实体
@Entity
@Table(name = "worksite")
public class Worksite {
private long id;
private String name;
private Double longitude;
private Double latitude;
private Set<WorksiteDevice> worksiteDevices = new HashSet<WorksiteDevice>();
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "worksite_id")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
@OneToMany(mappedBy = "worksite", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true )
public Set<WorksiteDevice> getWorksiteDevices() {
return worksiteDevices;
}
public void setWorksiteDevices(Set<WorksiteDevice> worksiteDevices) {
this.worksiteDevices = worksiteDevices;
}
}
第二个实体: 设备名称在数据库中具有唯一约束。这是为了防止用户多次进入同一个设备
@Entity
@Table(name = "device")
public class Device {
private long id;
private String DeviceName;
private Set<WorksiteDevice> worksiteDevices = new HashSet<WorksiteDevice>();
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "device_id")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getDeviceName() {
return name;
}
public void setName(String name) {
this.deviceName = name;
}
@OneToMany(mappedBy = "device", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
public Set<WorksiteDevice> getWorksiteDevices() {
return worksiteDevices;
}
public void setWorksiteDevices(Set<WorksiteDevice> worksiteDevices) {
this.worksiteDevices = worksiteDevices;
}
加入表:
@Entity
@Table(name = "worksite_device")
public class WorksiteDevice {
private long id;
private Worksite worksite;
private Device device;
// additional fields
private Integer deviceCount;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "worksite_device_id")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "worksite_id")
private Worksite worksite;
public void setWorksite(Worksite worksite) {
this.worksite = worksite;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "device_id")
public void setDevice(Device device) {
this.device = device;
}
public Integer getDeviceCount() {
return deviceCount;
}
public void setDeviceCount(Integer deviceCount) {
this.deviceCount = deviceCount;
}
}
我有一个 DTO 类,我从用户界面中获取设备的名称和工作场所中使用的设备数量。
public class WorksiteDeviceDTO extends BaseDTO{
private Long id;
private int deviceCount;
private String deviceName;
private Worksite worksite;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getDeviceCount() {
return deviceCount;
}
public void setDeviceCount(Integer deviceCount) {
this.deviceCount = deviceCount;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
deviceName = deviceName;
}
}
我将 DTO 对象保存在一个列表中,并在保存到数据库之前对其进行迭代。这是我这样做的方法: 我首先保存工作站点对象,然后保存工作站点中使用的设备数量和名称
worksiteService.saveWorksite(worksite);
final Map<String, Geraete> deviceByName = worksiteDeviceDtos.stream()
.map(worksiteDeviceDTO::getDeviceName)
.map(this::getOrSaveDeviceByName)
.collect(Collectors.toMap(
Device::getDeviceName,
Function.identity()));
worksiteDeviceDtos.forEach(worksiteDeviceDTO -> {
final WorksiteDevice toSave = new WorksiteDevice();
toSave.setWorksite(worksite);
toSave.setDevice(deviceByName.get(worksiteDeviceDTO.getDeviceName()));
toSave.setDeviceCount(worksiteDeviceDTO.getDeviceCount());
worksiteDeviceService.saveWorksiteDevice(toSave);
我用这个方法检查数据库中是否存在设备名。如果是这样,我会把它拿回来。如果没有,我用新名称创建一个新对象。
@Transactional
public Device getOrSaveDeviceByName(String DeviceName) {
return DeviceNameService.findByName(DeviceName)
.orElseGet(() -> geraeteService.saveNewGeraetWithName(DeviceName));
}
当我在用户界面中更改设备名称并保留设备数量时,将使用修改后的名称创建一个新对象。我不知道如何解决这个问题。有人会有想法。我也尝试使用复合键,但我遇到了同样的问题
【问题讨论】:
标签: java spring-boot hibernate java-8