Родительский объект без необходимости обновляется при сохранении нового дочернего объекта

Мы используем объекты JPA и спящий режим для сохранения. У меня есть сущность Plan и сущность Escalation. Когда я создаю новую эскалацию и сохраняю ее, план также каким-то образом обновляется. Это обновление вызывает OptimisticLockException и предотвращает дальнейшие эскалации. Вот скелет кода -

@Entity
@Table(name = "T_ESCLT")
public class Escalation extends PersistentEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ESCLT_ID")
    private Integer id;

    @ReflectionCopy.Exclude
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CUST_RNEW_TASK_ID", nullable = false)
    private CustomerRenewalTask renewalTask;

    @ReflectionCopy.Exclude
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PLN_DSG_ID")
    private Plan plan;

public Escalation(CustomerRenewalTask task, Plan plan, String description) {
        Preconditions.checkNotNull(task);
        Preconditions.checkNotNull(description);

        this.renewalTask = task;
        this.plan = plan;
        this.description = description;
        this.creationTimestamp = DateUtils.currentTimestamp();
    }

Plan и CustomerRenewalTask в них не отображается эскалация. Когда я запускаю это

@Transactional
    public Result persist() {
        CustomerRenewalTask customerRenewalTask = customerRenewalTaskDao.findById(2);
        Plan plan = planDao.findById(16);
        planDao.detach(plan);
        Escalation escalation = new Escalation(customerRenewalTask, plan, "My Escalation");
        escalationDao.persist(escalation);
        return ok();
    }

Я вижу это в журнале консоли

DEBUG - insert into T_ESCLT (ESCLT_ID, OPTMSTC_LOCK_ID, ATRB_NM, CMNT_TXT, CRT_TS, ESCLT_DSCR, APP_LNK_TXT, PLN_DSG_ID, RT_BLCK_IND, CUST_RNEW_TASK_ID, RSLV_DT, RSLV_BY_USR_ID, RSLV_BY_USR_NM, ESCLT_STTS_CD, ESCLT_TYP_CD) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - update T_PLN_DSG set OPTMSTC_LOCK_ID=?, ASSOC_PLN_DSG_ID=?, BRTH_DT_RT_IND=?, PLN_EFF_DT=?, ELGBL_MBR_CNT=?, RNEW_PLN_DTL_XML=?, SUM_MBR_PRTCP_LIF_CNT=?, VLD_STTS_CD=?, PLN_NM=?, PLN_GRP_ID=?, PRNT_PLN_DSG_ID=?, PRTCP_MBR_CNT=?, PRTCP_PCT=?, PRTNR_PLN_DSG_ID=?, RT_CALC_XML=?, UW_VRFY_IND=?, SUM_VOL_AMT=? where PLN_DSG_ID=? and OPTMSTC_LOCK_ID=?

Я не хочу выпускать обновление по плану, так как на Plan ничего не изменилось. Я только что использовал план, чтобы создать эскалацию.


person Vinay    schedule 10.05.2016    source источник
comment
возможно, вы делаете что-то в planDao.detach(plan), которое обновляет атрибуты объекта Plan?   -  person Franck    schedule 10.05.2016
comment
Опубликуйте сопоставления для объекта Plan и реализации соответствующих методов в PlanDao.   -  person Dragan Bozanovic    schedule 10.05.2016
comment
по определению вы должны что-то делать с Plan, из-за чего Hibernate считает его грязным и требует обновления после flush()   -  person Dean Clark    schedule 10.05.2016
comment
Мне пришлось добавить planDao.detach(plan); который просто делает em().detach(plan); Это помешало обновлению Плана, но решение было отклонено при проверке кода. План и эскалация имеют однонаправленное сопоставление oneToMany, поэтому в плане нет свойства эскалации. Я напечатал объект плана до и после сохранения эскалации и не увидел никакой разницы. Я ничего не делаю, чтобы сделать план грязным, но hibernate думает иначе.   -  person Vinay    schedule 10.05.2016


Ответы (1)


Один из способов предотвратить это обновление — указать update=false для отдельных свойств объекта плана, но тем самым вы предотвратите обновление в таблице плана в целом.

Пожалуйста, проверьте, решает ли ваша проблема указание cascade = CascadeType.PERSIST.

@ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.PERSIST)
person shankarsh15    schedule 11.05.2016
comment
Я попробовал это в эскалации - @JoinColumn(name = PLN_DSG_ID) @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) план частного плана; но я продолжаю видеть SQL-запросы эскалации и обновления плана в журнале консоли. - person Vinay; 11.05.2016