Hibernate загружает LOBS при удалении из связанной сущности (разве это не должно быть Lazy)? - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть веб-приложение, использующее JPA и Hibernate для взаимодействия с БД.

Есть один общий репозиторий JPA, одна сущность, с которой у меня сейчас проблемы.Теперь при вызове метода удаления я получаю java.lang.OutOfMemoryError: Исключение пространства кучи Java.(это deleteByCreatedDateLessThan).

Когда в таблицах есть только некоторые записи (проверено с 20), это работает нормально, но для реальной нагрузки до 20.000.

После анализа дампа этоОказалось, что приложение загружает весь IbGeneratedData.IbPdf & IbGeneratedData.IbXml из базы данных (заполнил 80% пространства кучи).
Как я могу это остановить?Для удаления нужно просто проверить идентификаторы, чтобы удалить их ...

Я также пытался @Basic(fetch=FetchType.LAZY) в LOB.

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
Hibernate: 4.3.7
Работа в базе данных Oracle

1 Ответ

0 голосов
/ 21 февраля 2019

1) LAZY - это только подсказка для провайдера персистентности, это не обязательно.

2) Способ работы deleteBy веснойData Jpa, который является правильным в соответствии со стандартами JPA, заключается в том, что он сначала загружает все объекты в контекст постоянства, а затем вызывает delete(entity) для каждого из результатов.

Решение

Создайте запрос на обновление и запустите его в новой транзакции (распространение. REQUIRES_NEW):

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

Это исключит загрузку сущностей в контекст постоянства и выполнит прямое пакетное удаление.

...