我正在尝试与休眠模式建立多对多关系,但它并没有达到我的预期。
这是我的实体。
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)
我期望休眠状态从FP_DOCUMENT_CURRENCY_LINK表中删除关系,但它也试图删除不再位于otherCurrency列表中的Currency:
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=?
我不希望那样发生。我应该从休眠中期待这种正常的行为吗?我不想从数据库中删除货币,因为这是一本字典,我只想在otherCurrency列表更改时删除关系。我该如何实现?
谢谢。
答案 0 :(得分:0)
您应在List<Currency> otherCurrency
中将LetterCreditAgreement
的级联类型定义为{CascadeType.PERSIST,CascadeType.MERGE}。这明确地告诉Hibernate仅持久化和合并从此类保存的更改。
进一步尝试避免使用列表,而是使用Set。
Vlad Mihalcea也有一篇不错的Blog-Article:https://vladmihalcea.com/the-best-way-to-use-the-manytomany-annotation-with-jpa-and-hibernate/,其中有更详细的内容。
我可以建议您定期阅读他的博客。