如何按日期从其超级实体类中删除所有子类别的实体

时间:2018-11-22 14:21:44

标签: java spring-data-jpa

我有一个ParentEntity,我从那里继承了所有子实体,如下所示:

@Data
@Entity
@Table(name = "parent", indexes = {@Index(columnList = "traceId"), @Index(columnList = "idType"), @Index(columnList = "companyId"), @Index(columnList = "created")})
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class ParentEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    private Long id;

    @Column(length = 150, nullable = false)
    private String idType;


    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created", nullable = false)
    private Date created;

    @CollectionTable(name = "unknown_fields", joinColumns=@JoinColumn(name = "id", referencedColumnName = "id"))
    @Cascade(value={CascadeType.ALL})
    @ElementCollection(fetch = EAGER)
    @MapKeyColumn(length = 50)
    Map<String, String> unknown = new HashMap<>();

    @PrePersist
    protected void onCreate() {
        created = new Date();
        idType = this.getClass().getAnnotation(Table.class).name();
    }
}

现在,我要删除created日期低于x的所有实体。由于我有很多子类,因此我绝对希望避免循环遍历每个子类。因此,我正在寻找一种方法,可以从ParentEntity中删除而不知道哪些孩子可能受到影响。

所以我创建了一个存储库:

@Transactional
public interface ParentEntityRepository extends JpaRepository<ParentEntity, Long> {

    void deleteAllInBatchByCreatedBefore(Date date);

}

现在,虽然parentEntityRepository.deleteAllInBatch();可以正常工作,但parentEntityRepository.deleteAllInBatchByCreatedBefore(Date.valueOf(isoDate));却无法正常工作。它进行了大量的选择,这些选择要花很多时间,直到最终死于Exception in thread "SimplePauseDetectorThread_0" java.lang.OutOfMemoryError: GC overhead limit exceeded为止。我希望更像delete from ? where created at < ?

1 个答案:

答案 0 :(得分:0)

看看文档,我怀疑这是不受支持的,并且框架在解析查询方法时只是忽略了AllInBatch部分-这就是为什么它仍然可以工作,但并没有达到您期望的原因。

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation

您可以定义自己的查询以获取预期的行为:

@Transactional
public interface ParentEntityRepository extends JpaRepository<ParentEntity, Long> {

    @Query("delete from ParentEntity p where p.created < :date) 
    void deleteAllInBatchByCreatedBefore(Date date);

}