EclipseLink如何从ManyToOne关系中的“一面”删除孤立实体

时间:2016-07-28 13:14:23

标签: java jpa eclipselink

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

我正在使用EclipseLink

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

ComponentEntity可与一个TransferDetailsEntity

相关联

TransfertDetailsEntity与一个或多个ComponentEntity相关。

我想要实现的是:当我删除引用TransfertDetails的最后一个Component时,应删除此TransfertDetails。 如果我将最后一个引用更改为TransfertDetails,则相同。

简而言之:只要任何组件没有引用TransfertDetails,就应该删除它。

作为一种解决方法,我称之为:

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

虽然有效,但由于搜索整个表格,因此效率不高。这很难看......

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

TransfertDetailsEntity:

@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;

    [...]

}

ComponentEntity:

@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;

    [...]

}

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

任何帮助表示赞赏

1 个答案:

答案 0 :(得分:1)

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

我能想到的最简单的方法是删除ComponentEntity,获取引用的TransfertDetailsEntity并检查其组件列表以查看是否有其他ComponentEntity引用,如果没有则将其删除。当你删除它时,你应该从TransfertDetailsEntity.components列表中删除每个ComponentEntity引用,所以这个列表应该是最新的,不会引起任何数据库命中。