У меня есть приложение Java Spring Boot со следующими объектами, связанными с приведенным ниже исключением.
Sпродукт
@Entity
@Table(
name = "product",
indexes = @Index(
name = "idx_asin",
columnList = "asin",
unique = true
)
)
public class SProduct implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "asin", unique = false, nullable = false, length = 10)
private String asin;
@Column(name = "rootcategory")
private Long rootcategory;
@Column(name = "imageCSV", unique = false, nullable = true, length = 350)
private String imagesCSV;
@Column(name = "title", unique = false, nullable = true, length = 350)
private String title;
private Date created;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "mainProduct", cascade = CascadeType.ALL)
private Set<FBT> fbts;
@OneToOne(fetch = FetchType.EAGER, mappedBy = "downloadProductId", cascade = CascadeType.ALL)
private Download download;
FBT
@Entity
@Table(
name = "fbt",
uniqueConstraints = {@UniqueConstraint(columnNames = {"main_product_id" , "collection"})},
indexes = {@Index(
name = "idx_main_product_id",
columnList = "main_product_id",
unique = false),
@Index(
name = "idx_product_fbt1id",
columnList = "product_fbt1_id",
unique = false),
@Index(
name = "idx_product_fbt2id",
columnList = "product_fbt2_id",
unique = false)
}
)
public class FBT implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne
@JoinColumn(name = "main_product_id")
private SProduct mainProduct;
@ManyToOne
@JoinColumn(name = "product_fbt1_id")
private SProduct sproductFbt1;
@ManyToOne
@JoinColumn(name = "product_fbt2_id")
private SProduct sproductFbt2;
@Column(name = "bsr", nullable = false)
private int bsr;
private Date collection;
У меня был следующий запрос в моем репозитории fbt
FBT findByMainProductAndCollection(SProduct mainProduct,Date collection);
что вызвало исключение вывода следующих сообщений, когда данные существуют в базе данных для mainProduct и collection, но в противном случае возвращает null.
<message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@69b7fcfc<rs=HikariProxyResultSet@325408381 wrapping com.mysql.jdbc.JDBC42ResultSet@108693fa></message>
<message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
<message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@47c40535<rs=HikariProxyResultSet@2005129089 wrapping com.mysql.jdbc.JDBC42ResultSet@9894f70></message>
<message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
<message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@5b0cd175<rs=HikariProxyResultSet@1598144514 wrapping com.mysql.jdbc.JDBC42ResultSet@6a7ff475></message>
<message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
<message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@f67e2cc<rs=HikariProxyResultSet@319200129 wrapping com.mysql.jdbc.JDBC42ResultSet@215b8a6></message>
<message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
<message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@5961afc0<rs=HikariProxyResultSet@1772496904 wrapping com.mysql.jdbc.JDBC42ResultSet@5956a59b></message>
<message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
<message>HHH000100: Fail-safe cleanup (collections) :
Я решил отказаться от вышеизложенного и написать @query для подсчета, поскольку мне нужно только определить, существуют ли данные или нет, и это предотвратило проблему, которая заставляет меня думать, что я должен изменить весь свой код для использования @query.
@Query("select count(*) as count from FBT where main_product_id = :id and collection= :collection")
int countByMainProductIdAndCollection(@Param("id") long id, @Param("collection") Date collection);
Хотя это также происходит, по-видимому, случайным образом при обновлениях в базе данных одного SProduct, когда продукт уже существует в базе данных.
SProductRepo.saveAndFlush(s);
Я говорю «случайным образом», поскольку 11 приложений, выполняющих один и тот же код, выходят через случайные промежутки времени с указанными выше сообщениями. Код не создает исключений, и 10000 успешных обновлений базы данных происходят с тем же кодом, который приводит к сбою. Код останавливается при попытке обновить базу данных, в которой он работал ранее.
""2018-12-28 00:56:06 [KeepaAPI-RetryScheduler] WARN org.hibernate.engine.loading.internal.LoadContexts - HHH000100: Fail-safe cleanup (collections) : org.hibernate.eng
ine.loading.internal.CollectionLoadContext@5c414639<rs=HikariProxyResultSet@1241510017 wrapping Result set representing update count of 13>
""2018-12-28 00:56:06 [KeepaAPI-RetryScheduler] WARN org.hibernate.engine.loading.internal.CollectionLoadContext - HHH000160: On CollectionLoadContext#cleanup, localLoa
dingCollectionKeys contained [1] entries
""2018-12-28 00:56:06 [KeepaAPI-RetryScheduler] WARN org.hibernate.engine.loading.internal.LoadContexts - HHH000100: Fail-safe cleanup (collections) : org.hibernate.eng
ine.loading.internal.CollectionLoadContext@5595c065<rs=HikariProxyResultSet@2140082434 wrapping Result set representing update count of 14>
""2018-12-28 00:56:06 [KeepaAPI-RetryScheduler] WARN org.hibernate.engine.loading.internal.CollectionLoadContext - HHH000160: On CollectionLoadContext#cleanup, localLoa
dingCollectionKeys contained [1] entries
""2018-12-28 00:56:06 [KeepaAPI-RetryScheduler] WARN org.hibernate.engine.loading.internal.LoadContexts - HHH000100: Fail-safe cleanup (collections) : org.hibernate.eng
ine.loading.internal.CollectionLoadContext@2956fe24<rs=HikariProxyResultSe
Кроме того, запрос SProduct findByAsin (String asin) вызывает ту же проблему, однако запрос в базе данных работает отлично, и это работало при весенней загрузке.
mysql> select * from product where asin = "B004FXJOQO";
| id | asin | created | imagecsv | rootcategory | title | 9 | B004FXJOQO | 2018-08-04 | 41T0ZwTvSSL.jpg,61V90AZKbGL.jpg,51AdEGCTZqL.jpg,51LDnCYfR0L.jpg,71bbIw43PjL.jpg | 228013 | Dual Voltage Tester, Non Contact Tester for High and Low Voltage with 3-m Drop Protection Klein Tools NCVT-2 |
1 row in set (0.00 sec)
Я хотел бы знать, каковы общие причины создания такого рода сообщений?
Почему они останавливают мое приложение, несмотря на операторы try catch вокруг операторов вставки, которые являются последними выполненными операторами в моем коде?
Есть ли полезные настройки отладки журнала для определения точной причины создания сообщений?
Есть ли способ отключить или контролировать эту функцию?
Пом
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-dependency-plugin.version>2.10</maven-dependency-plugin.version>
<maven.test.skip>true</maven.test.skip>
</properties>
<repositories>
<repository>
<id>Keepa</id>
<name>Keepa Repository</name>
<url>https://keepa.com/maven/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.18</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-oauth2</artifactId>
<version>v1-rev120-1.22.0</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-java6</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-gmail</artifactId>
<version>v1-rev48-1.22.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<dependency>
<groupId>com.myjeeva.digitalocean</groupId>
<artifactId>digitalocean-api-client</artifactId>
<version>2.16</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.keepa.api</groupId>
<artifactId>backend</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.jdeferred</groupId>
<artifactId>jdeferred-core</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>22.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build
Я увеличил объем памяти с 1 ГБ до 2 ГБ, однако объем памяти составляет только 30% от того, что доступно.
Есть мысли относительно того, в чем проблема?
Сталкивались ли вы с этой проблемой вместе с упомянутой? "java.lang.OutOfMemoryError: превышен предел накладных расходов сборщика мусора"




Похоже, вы загружаете в свое приложение огромное количество данных.
Метод
FBT findByMainProductAndCollection(SProduct mainProduct,Date collection);
загрузит все совпадающие данные. Но вам нужно только count, попробуйте запрос, который точно возвращает количество данных, а не все данные.
Один из способов сделать это - использовать упомянутый вами запрос, а другой -
Long countByMainProductAndCollection(SProduct mainProduct, Date collection);
Или
Boolean existsByMainProductAndCollection(SProduct mainProduct, Date collection)
Да, для SProductRepo.saveAndFlush (s) я сохраняю только один SProduct. Хотел бы разобраться в проблеме и получить ответы на эти вопросы за вознаграждение.
странно то, что эти методы findby должны возвращать только несколько записей. У меня такая же проблема при выполнении SProductRepo.findByAsin (asin); однако в базе данных есть только одна запись с этим asin, и я могу запросить ее. Это тайм-ауты, учитывая 1,5 миллиона заданий?
Во-первых, это ошибка гибернации, обрабатываемая org.hibernate.engine и не имеющая ничего общего с Spring Boot.
Это может произойти, если вы извлекаете большие объемы данных, например десятки тысяч сущностей, с помощью ваших запросов HQL.
Это также может иметь место, если вы сопоставили ассоциацию «один ко многим», которая имеет множество дочерних сущностей, и из-за двунаправленного сопоставления набор результатов реплицируется бесконечно.
См. Ссылку ниже для получения советов по высокопроизводительному JPA.
https://vladmihalcea.com/14-high-performance-java-persistence-tips/
Можно с @Fetch(value = SELECT) попробовать?
@OneToMany(fetch = FetchType.EAGER, mappedBy = "mainProduct", cascade = CascadeType.ALL)
@Fetch(value=FetchMode.SELECT)
private Set<FBT> fbts;
В моем случае это было из-за того, что сущности рекурсивно вызывали хэш-код друг друга, если вы используете lombock, удалите его и сделайте самостоятельно. Поместите точку останова отладчика на методы двух хэш-кодов. Вы поймете, что они зовут друг друга. Удалите, например, из метода хэш-кода первой сущности ссылку второй сущности.
Если вы используете @Data, удалите его и повторите попытку. Данные эквивалентны Getter Setter RequiredArgsConstructor ToString EqualsAndHashCode.
с lombok вы можете использовать атрибут exclude с анотацией EqualsAndHashCode, чтобы исключить поля, которые вызывают переполнение
Спасибо! Это было единственное решение, которое сработало для меня! Я реализовал equals и hashCode для своих POJO, и он начал работать для меня !!!
У меня была эта проблема при использовании Set, но когда я все-таки перехожу в список, она решается Вы должны использовать
private List<FBT> fbts;
В моем случае я использовал автоматически сгенерированный метод Repository, который вернул List<MyData>. Оказывается, 2000 сущностей - это слишком много для Hibernate. Я исправил проблему, заменив его методом, возвращающим Stream<MyData>, а затем сопоставив объекты с созданной вручную структурой MyDataDetached.
В моем случае я получал "java.lang.StackOverflowError: null" (ранее также несколько сообщений журнала «Безотказная очистка (сборники)») при запуске метода JPA спасти для определенного объекта с двунаправленными отношениями @ManyToOne и @Один ко многим. Любопытно, что он не работал только с Oracle и PostgreSQL, но работал нормально в MySQL, MariaDB и SQLServer.
Итак, проблема заключалась в том, что ломбок с Хэш-код в объектах @Один ко многим.
Я решил установить эту аннотацию в этих объектах на уровне класса:
@EqualsAndHashCode (exclude = "nameAttributeInThisClassWithOneToMany")
Спас мой день, чувак, это потрясающе!
Попробуйте
existsByMainProductAndCollection(), если вам не нужны данные