情况:NotificationProfile实体具有嵌入IntegrationNotificationCutOff的NotificationProfileIntegration实体的集合。它是遗留数据库,我无法修改它。有人认为将时间存储为“HH:mm”字符串是一个好主意,但我需要使用日期对象。这就是我有这些转换回调和瞬态日期字段的原因。
当我这样做时(对于现有的个人资料实体)
entityManager.merge(profile);
我希望在NotificationProfileIntegration上调用@PreUpdate,并将日期转换为它们的字符串表示并持久保存到DB。而是首先调用@PostLoad方法,然后调用@PreUpdate。
因此,如果我在cutOff实例中设置它永远不会持久化,因为在@PostLoad方法中创建了cutOffs的新实例,因为由于hibernate的这个特性它是null的
当@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之后 - 在更新之前触发select并且我对实体的更改在某个地方“丢失”