persisting object with long[][] arrays of array

#1

Hi,

I have an object I am trying to persist (java) - It has several fields of type long[][].

It is taking very long to persist and sometimes never finish - it hangs on getTransaction().commit();

Here is the object:

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;


@Entity
public class TESTObject implements Serializable{
    private static final long serialVersionUID = 1L;
    public @Id String id;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) public long[] time;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private long[][] a1;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private long[][] a2;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private long[][] b1;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private long[][] b2;

    public TESTObject(String ids, long[] time, long[][] a1, long[][] a2, long[][] b1, long[][] b2) {
        this.id = ids;
        this.time = time;
        this.a1 = a1;
        this.a2 = a2;
        this.b1 = b1;
        this.b2 = b2;
    }
}

and the test script - which takes about 50sec to complete on my mac.

private static long[][] random2(int n){
        long[][] ret = new long[n][1];
        return ret;
    }
    public static void main(String[] args) {
        EntityManagerFactory EMF = Persistence.createEntityManagerFactory("TESTDB.odb");
        EntityManager emg =EMF.createEntityManager();
        int n = 100_000;
        TESTObject obj = new TESTObject(
                "ID1",
                new long[n],
                random2(n),
                random2(n),
                random2(n),
                random2(n));
        emg.getTransaction().begin();
        emg.persist(obj);
        emg.getTransaction().commit();
        emg.clear();
        emg.close();
        EMF.close();
    }

as a comparison I ran it with simple arrays (not arrays of arrays) - 

 

@Entity
public class TESTObject2 implements Serializable{
    private static final long serialVersionUID = 1L;
    public @Id String id;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) public long[] time;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private long[] a1;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private long[] a2;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private long[] b1;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private long[] b2;

    public TESTObject2(String ids, long[] time, long[] a1, long[] a2, long[] b1, long[] b2) {
        this.id = ids;
        this.time = time;
        this.a1 = a1;
        this.a2 = a2;
        this.b1 = b1;
        this.b2 = b2;
    }
}

and the test code took less than 1sec to complete:

private static long[] random2(int n){
        long[] ret = new long[n];
        return ret;
    }
    public static void main(String[] args) {
        EntityManagerFactory EMF = Persistence.createEntityManagerFactory("TESTDB2.odb");
        EntityManager emg =EMF.createEntityManager();
        int n = 100_000;
        TESTObject2 obj = new TESTObject2(
                "ID1",
                new long[n],
                random2(n),
                random2(n),
                random2(n),
                random2(n));
        emg.getTransaction().begin();
        emg.persist(obj);
        emg.getTransaction().commit();
        emg.clear();
        emg.close();
        EMF.close();
    }

note that the dimension of the first object's arrays of arrays are n x 1 - so the amount of data saved is exactly the same -

So it looks like there is something ObjectDb (2.7.1) does not like about arrays of arrays.

Thanks

EKK

 

#2

A long[][] array is represented in Java as an array of arrays.

new long[100000][1] is actually one long array of 100,000 small arrays.

Persisting 100,000 small objects (arrays) to the database is expected to take much more time than persisting one large object of the same total size.

Consider using large single dimension arrays, if possible, as it is expected to be more efficient in Java (as you save a lot of small allocations and space for references), not just in persisting to the database.

ObjectDB Support

Reply