gpt4 book ai didi

java - 有没有办法删除 @OneToMany 关系(使用 JoinTable)中的子实体,而无需获取完整集合?

转载 作者:行者123 更新时间:2023-12-01 12:47:24 25 4
gpt4 key购买 nike

我有以下类/关系(getter 和 setter 未显示,但存在):

public class Contract implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;

@Version
@Column(name = "version")
private Integer version;

private String number;
private String volume;

@OneToMany(cascade=CascadeType.REMOVE)
@JoinTable(joinColumns = @JoinColumn(name = "contract_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "attachment_id", referencedColumnName = "id"))
private List<Attachment> attachments;
}

public class Attachment implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;

@Version
@Column(name = "version")
private Integer version;

@Lob
@Basic(fetch=FetchType.LAZY)
@Column(length=2147483647)
private byte[] contents;


private String name;
}

根据我的需求/设计,我使用连接表。

如果我想从契约(Contract)中删除附件,我需要加载契约(Contract),然后循环遍历所有附件,直到找到我要删除的附件并将其从列表中删除。

虽然这很实用,但它需要大量的数据库通信。如果附件列表很长,内容也很大,也需要很大的带宽。

还有其他方法可以删除它吗?如果我尝试直接删除附件(例如:Attachment.findById().delete()),由于 FK 关系,它会失败 - 不是吗? (我还没有尝试过,但我怀疑)。

此外,如果我有一个非常大的附件列表,则逐一迭代它们直到找到正确的附件也不是很有效。

JPA 是否提供任何其他/更好的解决方案?

最佳答案

我知道有一个解决方案 - 您可以为连接表创建一个实体类。

您必须在 @JoinTable 注释(name 属性)中为联接表指定名称,例如 ContractAttachment。然后您可以创建实体:

@Entity(name = "ContractAttachment") // note the same name of table
@IdClass(ContractAttachmentId.class)
public class ContractAttachment implements Serializable {

static final long serialVersionUID = 1L;

@Id
@ManyToOne
@JoinColumn(name="contract_id") // same mappings for columns
private Contract contract;

@Id
@ManyToOne(cascade = CascadeType.REMOVE)
@JoinColumn(name="attachment_id") // same mappings for columns
private Attachment attachment;

// you will also have to override equals and hashcode methods here

}

ContractAttachmentId应如下所示:

public class ContractAttachmentId implements Serializable {
private long contract; // note the same fields names
private long attachment;

// this class should also implement hashcode and equals
}

现在您可以删除连接表中的单个条目,甚至可以删除附件对象。

ContractAttachment ca = em.createQuery("select ca from ContractAttachment ca " +
"where ca.contract = :contract and ca.attachment = :attachment")
.setParameter("contract", selectedContract)
.setParameter("attachement", selectedAttachment)
.getSingleResult();
em.remove(ca);

关于java - 有没有办法删除 @OneToMany 关系(使用 JoinTable)中的子实体,而无需获取完整集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24561691/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com