Что вызывает Spring Boot? Отказоустойчивая очистка (коллекции) - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть приложение Java Spring Boot со следующими объектами, связанными с приведенным ниже исключением

SProduct

@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 и коллекции, но в противном случае возвращает ноль,

  <message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@69b7fcfc&lt;rs=HikariProxyResultSet@325408381 wrapping com.mysql.jdbc.JDBC42ResultSet@108693fa&gt;</message>
  <message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
  <message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@47c40535&lt;rs=HikariProxyResultSet@2005129089 wrapping com.mysql.jdbc.JDBC42ResultSet@9894f70&gt;</message>
  <message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
  <message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@5b0cd175&lt;rs=HikariProxyResultSet@1598144514 wrapping com.mysql.jdbc.JDBC42ResultSet@6a7ff475&gt;</message>
  <message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
  <message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@f67e2cc&lt;rs=HikariProxyResultSet@319200129 wrapping com.mysql.jdbc.JDBC42ResultSet@215b8a6&gt;</message>
  <message>HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries</message>
  <message>HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@5961afc0&lt;rs=HikariProxyResultSet@1772496904 wrapping com.mysql.jdbc.JDBC42ResultSet@5956a59b&gt;</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 используют мои операторы вставки, которые являются последними выполняемыми операторами в моем коде?

Есть ли полезные настройки отладки журнала, чтобы определить точную причину, по которой сообщения генерируются?

Есть ли способ отключить или управлять этой функцией?

Pom

  <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% от доступного.

Есть мысли по поводу проблемы?

С уважением, Алекс

Ответы [ 4 ]

0 голосов
/ 19 июля 2019

В моем случае это было из-за того, что сущности рекурсивно вызывали хеш-код друг друга, если вы используете lombock, удалите его и сделайте его сами. Поместите точку останова отладчика на методы двух хеш-кодов.Вы поймете, что они зовут друг друга.Удалите, например, из метода хеш-кода первого объекта ссылку на второй объект.

0 голосов
/ 03 января 2019

Во-первых, это ошибка Hibernate, обработанная org.hibernate.engine и не имеющая ничего общего с Spring Boot.

Это может произойти, если вы извлекаете большие объемы данных, например десятки тысяч объектов сваши запросы HQL.

Это также может иметь место, если вы сопоставили однозначную ассоциацию, которая имеет множество дочерних объектов, и из-за двунаправленного сопоставления набор результатов реплицируется бесконечно.

Обратитесь к ссылке ниже для получения информации о JPA Советы.

https://vladmihalcea.com/14-high-performance-java-persistence-tips/

0 голосов
/ 03 января 2019

Можете ли вы попробовать с @Fetch(value = SELECT)?

@OneToMany(fetch = FetchType.EAGER, mappedBy = "mainProduct", cascade = CascadeType.ALL)
@Fetch(value=FetchMode.SELECT)
private Set<FBT> fbts;
0 голосов
/ 28 декабря 2018

Похоже, вы загружаете огромное количество данных в ваше приложение.

Метод

FBT findByMainProductAndCollection(SProduct mainProduct,Date collection);

загрузит все соответствующие данные.Но вам нужно только подсчитать, попробуйте запрос, который в точности возвращает количество данных вместо всех данных.

Один из способов сделать это - использовать упомянутый вами запрос, а другой способ -

Long countByMainProductAndCollection(SProduct mainProduct, Date collection);

или

Boolean existsByMainProductAndCollection(SProduct mainProduct, Date collection)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...