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 引用都应该将其删除,因此该列表应该是最新的并且不会导致任何数据库命中。
搜索答案后,我看到了 @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 引用都应该将其删除,因此该列表应该是最新的并且不会导致任何数据库命中。