LoginSignup
0
0

More than 5 years have passed since last update.

EclipseLinkをつかってDBプログラミングをする part1

Posted at

始めに

業務で必要になりそうなので、EclipseLinkを使ってDBプログラミングをしてみた

サンプルプログラム

1の連番をDBにインサートするプログラムを書いてみた

InsertLogic.java
package logic;

import java.util.Date;
import java.util.stream.Stream;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import entiry.SequeceNum;


public class InsertLogic {
    public static void main(String args[]){
        new InsertLogic().doLogic();
    }

    public void doLogic(){
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("myUnitInPersistenceXML");
        EntityManager em = factory.createEntityManager();
        long start =System.currentTimeMillis();
        System.out.println("insert start");
        em.getTransaction().begin();

        Stream.iterate(1l, s->s+1)
        .limit(1000000000000l)
        .map(i->createSequeceNum(i))
        .forEach(o->doInsert(em,o));
        System.out.println("insert End");
        long ends =System.currentTimeMillis();
        System.out.println(String.format("かかった時間  %d", (ends - start)));

    }

    private static SequeceNum createSequeceNum(long i){
        SequeceNum myEntity = new SequeceNum();
        myEntity.setId(i);
        return myEntity;
    }
    private static void doInsert(EntityManager em,SequeceNum entity){
        em.persist(entity);
        if(entity.getId()%100000 == 0){
            em.getTransaction().commit();
            em.getTransaction().begin();
        }
    }
}
SequeceNum.java
package entiry;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class SequeceNum {
    @Id
    private long id;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }
}

このまま実行すると、以下のエラーがでる

[EL Info]: 2017-12-03 21:56:37.505--ServerSession(336400944)--EclipseLink, version: Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5
[EL Info]: connection: 2017-12-03 21:56:38.156--ServerSession(336400944)--file:/C:/Users/takayoshi/workspace/Pazzle/bin/_myUnitInPersistenceXML login successful
insert start
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.createObjectChangeSet(ObjectBuilder.java:2872)
    at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.createObjectChangeSetThroughComparison(DeferredChangeDetectionPolicy.java:155)
    at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.createObjectChangeSet(DeferredChangeDetectionPolicy.java:146)
    at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChanges(DeferredChangeDetectionPolicy.java:91)
    at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChangesForExistingObject(DeferredChangeDetectionPolicy.java:56)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:664)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1516)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
    at logic.InsertLogic.doInsert(InsertLogic.java:43)
    at logic.InsertLogic.lambda$2(InsertLogic.java:28)
    at logic.InsertLogic$$Lambda$6/2137034273.accept(Unknown Source)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
    at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
    at java.util.stream.SliceOps$1$1.accept(Unknown Source)
    at java.util.Spliterators$IteratorSpliterator.tryAdvance(Unknown Source)
    at java.util.stream.ReferencePipeline.forEachWithCancel(Unknown Source)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(Unknown Source)
    at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
    at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
    at java.util.stream.ReferencePipeline.forEach(Unknown Source)
    at logic.InsertLogic.doLogic(InsertLogic.java:28)
    at logic.InsertLogic.main(InsertLogic.java:15)
[EL Info]: connection: 2017-12-03 22:23:39.469--ServerSession(336400944)--file:/C:/Users/takayoshi/workspace/Pazzle/bin/_myUnitInPersistenceXML logout successful

どうやら、メモリに実行した結果がキャッシュに残っているらしく、ヒープ領域が枯渇したようだ
ちなみに、ヒープが枯渇した時にDBにインサートした行数は以下の通り

  COUNT(*)
----------
   2400001

どうやら、何の工夫もなくInsert文を実行するとシンプルなデータ構造でも25万件程度でエラーが発生するらしい
改善案は次のエントリで書いてみる

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0