作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下类/关系(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/
我是一名优秀的程序员,十分优秀!