Hibernate在从相关实体删除时加载LOBS(不应该是懒惰的)吗?

问题描述 投票:2回答:1

我有一个使用JPA和Hibernate进行数据库交互的Web应用程序。

有一个generiec JPA存储库,我现在遇到了一个问题。现在,在调用delete方法时,我得到一个java.lang.OutOfMemoryError:Java堆空间异常。 (它是deleteByCreatedDateLessThan)。

当表中只有一些条目(用20测试)时,这可以正常工作,但实际负载高达20.000。

在分析转储后,结果发现应用程序正在从数据库加载整个IbGeneratedData.IbPdf和IbGeneratedData.IbXml(填充了80%的堆空间)。 我怎么能阻止这个?要删除它,只需检查ID以删除它们...

我在LOB上尝试了@Basic(fetch=FetchType.LAZY)

public interface ResponseRepository extends JpaRepository<IbResponse, String>, JpaSpecificationExecutor<IbResponse> {
    @Modifying
    void deleteByCreatedDateLessThan(Date maxAgedDate);

    Collection<IbResponse> findByOwningUserIdEquals(String id, Sort sort);
}



@Entity(name = "IbResponse")
@Table(name = "IB_RESPONSE")
public class IbResponse implements Serializable {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "ID")
    private String id;

    @ManyToOne(fetch = FetchType.LAZY, optional = false, targetEntity = IbUser.class)
    @JoinColumn(name = "USER_ID", updatable = false)
    private IbUser owningUser;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "GENERATED_DATA_ID")
    private IbGeneratedData generatedData;

    ...
}

@Entity(name = "IbGeneratedData")
@Table(name = "IB_GENERATED_DATA")
public class IbGeneratedData implements Serializable {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "ID")
    private String id;

    @Lob
    @Column(name = "PDF")
    private byte[] IbPdf;

    @Lob
    @Column(name = "XML")
    private byte[] IbXml;

    ...
}

Spring-data-jpa:1.7.0 休眠:4.3.7 在Oracle数据库上运行

java hibernate jpa lazy-loading
1个回答
2
投票

1)LAZY只是持久性提供者的暗示,它不是必须的。

2)deleteBy在Spring Data Jpa中的工作方式,根据JPA标准是正确的,它将所有实体首先加载到持久化上下文中,然后为每个结果调用delete(entity)

创建更新查询并在新事务中运行它(propagation.REQUIRES_NEW):

@Modifying
@Query("delete from IbResponse i where i.createdDate < :date", )
void deleteByCreatedDateLessThan(@Param("date") Date date);

这将省略将实体加载到持久性上下文中并执行直接批量删除。

© www.soinside.com 2019 - 2024. All rights reserved.