EclipseLink 如何从 ManyToOne 关系中的 "one side" 中删除孤立实体

EclipseLink how to delete orphans entities from the "one side" in a ManyToOne relationship

搜索答案后,我看到了 @PrivateOwner 注释,但它并没有解决我的问题。

我正在使用 EclipseLink

问题是: 我有 2 个与 1:n 双向关系相关的实体。

一个ComponentEntity可以关联一个TransferDetailsEntity

一个TransfertDetailsEntity与一个或多个ComponentEntity有关。

我想实现的是:当我删除最后一个引用 TransfertDetails 的 Component 时,应该删除这个 TransfetDetails。 如果我更改对 TransfertDetails 的最后引用,则相同。

简而言之:一旦 TransfertDetails 未被任何组件引用,就应该将其删除。

作为解决方法,我将此方法称为:

@Override
public void removeOrphanTransfer() {
    for (TransferDetailsEntity transfer : transferDetailsRepository.findAll()) {
        if (transfer.getComponents().isEmpty()) {
            transferDetailsRepository.delete(transfer);
        }
    }
}

可行,但效率不高,因为它会搜索整个 table。而且很丑...

这是实体的(简化)代码:

传输详细信息实体:

@Entity
@Table(name = TransferDetailsEntity.TABLE_NAME)
@Getter
@Setter
@NoArgsConstructor
public class TransferDetailsEntity extends AbstractEntity {

    [...]
    @Id
    @Column(name = ID, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    [...]

    @OneToMany(mappedBy = "transferDetails")
    private List<ComponentEntity> components;

    [...]

}

组件实体:

@Entity
@Table(name = ComponentEntity.TABLE_NAME, uniqueConstraints = @UniqueConstraint(name = ComponentEntity.TABLE_NAME
        + AbstractEntity.SEPARATOR + AbstractEntity.CONSTRAINT,
        columnNames = { ComponentEntity.COLUMN_NAME_SERIAL, ComponentEntity.COLUMN_NAME_TYPE }))
@Getter
@Setter
@ToString(callSuper = true, exclude = { "parent" })
@NoArgsConstructor
public class ComponentEntity extends AbstractEntity {

    [...]

    @Id
    @Column(name = ID, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    [...]

    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = COLUMN_TRANSFER_DETAILS)
    private TransferDetailsEntity transferDetails;

    [...]

}

如前所述,@OneToMany 注释(在 TransfertDetailsEntity 中)的 @PrivateOwner 不起作用...

感谢任何帮助

没有自动 JPA 或 EclipseLink 功能可以为您执行此操作,您的应用程序必须处理此操作。

我能想到的最简单的方法是删除 ComponentEntity,获取引用的 TransfertDetailsEntity 并检查其组件列表以查看它是否有其他 ComponentEntity 引用,如果没有则将其删除。无论如何删除 TransfertDetailsEntity.components 列表中的每个 ComponentEntity 引用都应该将其删除,因此该列表应该是最新的并且不会导致任何数据库命中。