web-dev-qa-db-ja.com

Spring Boot Fail-safe cleanup(collections)が発生する原因

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およびコレクションのデータが存在する場合に次のメッセージが出力例外になりますが、それ以外の場合はnullが返されます。

  <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);

これは、製品がすでにデータベースに存在する場合、1つの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)

私が知りたいのは、この種のメッセージが生成される一般的な理由は何ですか?

コードで最後に実行されたステートメントである挿入ステートメントの周りに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 GBから2 GBに増やしましたが、メモリは使用可能な容量の30%にすぎません。

問題が何かについて何か考えはありますか?

アレックスよろしく

8
conteh

@Fetch(value = SELECT)で試すことができますか?

@OneToMany(fetch = FetchType.EAGER, mappedBy = "mainProduct", cascade = CascadeType.ALL)
@Fetch(value=FetchMode.SELECT)
private Set<FBT> fbts;
1
fhery021

私の場合は、エンティティがお互いのハッシュコードを再帰的に呼び出すためでした。ロンボックを使用してそれを削除し、自分で作成した場合.2つのハッシュコードのメソッドにデバッガーのブレークポイントを配置します。あなたは彼らがお互いを呼んでいると思うでしょう。たとえば、最初のエンティティのハッシュコードメソッドから2番目のエンティティのリンクを削除します。

7
Vahan Yeghyan

まず、これはorg.hibernate.engineによって処理される休止状態エラーであり、Spring Bootとは何の関係もありません。

これは、HQLクエリで何万ものエンティティなどの大量のデータをフェッチしている場合に発生する可能性があります。

これは、多くの子エンティティを持つ1対多の関連付けをマッピングしていて、双方向のマッピングにより結果セットが無限に複製されている場合にも当てはまります。

高性能JPAのヒントについては、以下のリンクを参照してください。

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

5
apoorvakash

アプリケーションに大量のデータを読み込んでいるようです。

方法

FBT findByMainProductAndCollection(SProduct mainProduct,Date collection);

一致するすべてのデータをロードします。しかし、必要なのは、すべてのデータではなく正確にデータの数を返すクエリを試してみることだけです。

1つの方法は、あなたが言及したクエリを使用することであり、他の方法は

Long countByMainProductAndCollection(SProduct mainProduct, Date collection);

または

Boolean existsByMainProductAndCollection(SProduct mainProduct, Date collection)
1
Vikram Singh