Отображение Hibernate Many-To-Many удаляет дочернюю сущность - PullRequest
0 голосов
/ 03 июля 2018

Я пытаюсь создать отношение «многие ко многим» в спящем режиме, но оно не работает так, как я ожидаю.

Вот мои сущности.

LetterCreditAgreement:

@Canonical
@CompileStatic
@Entity
@Table(name = "FP_LETTER_OF_CREDIT_AGREEMENT")
class LetterCreditAgreement {
    @Id
    @Column(name = "DOC_ID")
    Long id

    ...

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
        name = "FP_DOCUMENT_CURRENCY_LINK",
        joinColumns = @JoinColumn(name = "DOC_ID"),
        inverseJoinColumns = @JoinColumn(name = "CURRENCY_ID"))
    List<Currency> otherCurrency

    ...
}

Валюта (которая является словарем и представлена ​​как представление в базе данных):

@Entity
@Table(name = "V_CURRENCY")
@Canonical
@CompileStatic
@EqualsAndHashCode(callSuper = true)
class Currency extends SuperEntity {
    @Column(name = "name")
    String name

    @Column(name = "short_name")
    String shortName

    @Column(name = "ident")
    String ident

    @Column(name = "code")
    String code

    @ManyToOne
    @JoinColumn(name = "type_id")
    MeasureUnitType type
}

Связанная сущность:

@Entity
@Table(name = "FP_DOCUMENT_CURRENCY_LINK")
@Canonical
@CompileStatic
class DocumentCurrencyLink {

   @EmbeddedId
   DocumentCurrencyPK pk

   @Embeddable
   @Canonical
   @CompileStatic
   static class DocumentCurrencyPK implements Serializable {
       @ManyToOne(fetch = FetchType.LAZY)
       @JoinColumn(name = "doc_id")
       Document document

       @ManyToOne(fetch = FetchType.LAZY)
       @JoinColumn(name = "currency_id")
       Currency currency
   }
}

Код, который сохраняет или обновляет основной объект:

LetterCreditAgreement detached = mapper.toEntity(form.data)
LetterCreditAgreement loc = repository.findOne(locId)

...

if (detached.otherCurrency != null) {
        entityUtil.mergeLists(loc.otherCurrency, detached.otherCurrency)
}

...

loc = repository.save(detached)

Я ожидаю, что hibernate удалит отношения из таблицы FP_DOCUMENT_CURRENCY_LINK, но также пытается удалить валюту, которой больше нет в списке других валют:

Hibernate: delete from table.fp_document_currency_link where doc_id=?
Hibernate: insert into table.fp_document_currency_link (doc_id, currency_id) values (?, ?)
Hibernate: insert into table.fp_document_currency_link (doc_id, currency_id) values (?, ?)
Hibernate: insert into table.fp_document_currency_link (doc_id, currency_id) values (?, ?)
Hibernate: insert into table.fp_document_currency_link (doc_id, currency_id) values (?, ?)

Это нормально, но следующее:

Hibernate: delete from table.v_currency where id=?

Я не хочу, чтобы это случилось. Это нормальное поведение, которое я должен ожидать от спящего? Я не хочу, чтобы валюта удалялась из базы данных, потому что это словарь, я просто хочу удалить отношения при изменении списка других валют. как мне этого добиться?

Спасибо.

1 Ответ

0 голосов
/ 03 июля 2018

Вы должны определить тип каскада List<Currency> otherCurrency в LetterCreditAgreement для {CascadeType.PERSIST, CascadeType.MERGE}. Это явно указывает Hibernate только на изменения Persist и Merge, сохраненные из этого класса. Далее старайтесь избегать использования List, лучше используйте Set. Есть также хорошая статья-блог от Влада Михальча: https://vladmihalcea.com/the-best-way-to-use-the-manytomany-annotation-with-jpa-and-hibernate/, которая углубляется в детали.

Могу просто порекомендовать регулярно читать его блог.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...