JPA PostLoad和PreUpdate with Embedded columns

时间:2013-06-11 13:10:13

标签: java hibernate jpa embedding

情况: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并且我对实体的更改在某个地方“丢失”

0 个答案:

没有答案