情况:NotificationProfile 实体具有嵌入了 IntegrationNotificationCutOff 的 NotificationProfileIntegration 实体的集合。它是旧数据库,我无法修改它。有人认为将时间存储为“HH:mm”字符串是个好主意,但我需要使用日期对象。这就是为什么我有这些转换回调和瞬态日期字段的原因。
当我这样做时(对于现有的配置文件实体)
entityManager.merge(profile);
,我希望在 NotificationProfileIntegration 上调用 @PreUpdate 并将日期转换为它们的字符串表示形式并保存到数据库中。相反,首先调用 @PostLoad 方法,然后调用 @PreUpdate。因此,如果我在 cutOff 实例中设置某些内容,它永远不会持久化,因为在 @PostLoad 方法中创建了新的 cutOffs 实例,因为由于休眠的此功能,它为空
当 @Embedded 对象中的所有值都为 null 时,Hibernate 会将父对象中的字段设置为 null。
我该如何处理这种情况?谢谢你。
@Entity
@Table(name = "NOTIFICATION_PROFILES")
public class NotificationProfile extends AbstractEntity<Long> {
@OneToMany(mappedBy = "notificationProfile", cascade = CascadeType.ALL, orphanRemoval = true)
private Collection<NotificationProfileIntegration> profileIntegrations;
....
}
@Entity
@Table(name = "NOTIFICATION_PROFILE_INTEG")
public class NotificationProfileIntegration extends AbstractEntity<Long> {
@Embedded
private IntegrationNotificationCutOff cutOffs;
@Embedded
private IntegrationNotificationAverageCount averageShipments;
@PostLoad
public void initEmbeded() {
if (cutOffs == null) {
cutOffs = new IntegrationNotificationCutOff();
}
if (averageShipments == null) {
averageShipments = new IntegrationNotificationAverageCount();
}
cutOffs.convertToDates();
}
@PreUpdate
@PrePersist
private void formatCutOffs() {
if (cutOffs != null) {
cutOffs.convertToValues();
}
}
}
@Embeddable
public class IntegrationNotificationCutOff {
@Column(name = "NPI_CUT_OFF_TIME_MON")
private String monday;
@Column(name = "NPI_CUT_OFF_TIME_TUE")
private String tuesday;
@Column(name = "NPI_CUT_OFF_TIME_WED")
private String wednesday;
@Column(name = "NPI_CUT_OFF_TIME_THU")
private String thursday;
@Column(name = "NPI_CUT_OFF_TIME_FRI")
private String friday;
@Column(name = "NPI_CUT_OFF_TIME_SAT")
private String saturday;
@Column(name = "NPI_CUT_OFF_TIME_SUN")
private String sunday;
@Transient
private Date mondayDate;
@Transient
private Date tuesdayDate;
@Transient
private Date wednesdayDate;
@Transient
private Date thursdayDate;
@Transient
private Date fridayDate;
@Transient
private Date saturdayDate;
@Transient
private Date sundayDate;
public void convertToDates() {
SimpleDateFormat dateFormat = getDateFormat();
mondayDate = nullSafeConvert(monday, dateFormat);
tuesdayDate = nullSafeConvert(tuesday, dateFormat);
wednesdayDate = nullSafeConvert(wednesday, dateFormat);
thursdayDate = nullSafeConvert(thursday, dateFormat);
fridayDate = nullSafeConvert(friday, dateFormat);
saturdayDate = nullSafeConvert(saturday, dateFormat);
sundayDate = nullSafeConvert(sunday, dateFormat);
}
public void convertToValues() {
SimpleDateFormat dateFormat = getDateFormat();
monday = nullSafeFormat(mondayDate, dateFormat);
tuesday = nullSafeFormat(tuesdayDate, dateFormat);
wednesday = nullSafeFormat(wednesdayDate, dateFormat);
thursday = nullSafeFormat(thursdayDate, dateFormat);
friday = nullSafeFormat(fridayDate, dateFormat);
saturday = nullSafeFormat(saturdayDate, dateFormat);
sunday = nullSafeFormat(sundayDate, dateFormat);
}
private String nullSafeFormat(Date date, SimpleDateFormat dateFormat) {
if (date == null) {
return null;
}
return dateFormat.format(date);
}
private SimpleDateFormat getDateFormat() {
return new SimpleDateFormat("HH:mm");
}
private Date nullSafeConvert(String day, SimpleDateFormat dateFormat) {
if (day == null) {
return null;
}
try {
return dateFormat.parse(day);
} catch (ParseException e) {
return null;
}
}
}
编辑 似乎嵌入对这种行为没有任何影响。当我将其重构为单个实体时,问题仍然存在:在调用 createOrUpdate 之后 - 在更新之前触发了选择,并且我对实体的更改在某处“丢失”