When scanning too many entity in jpa hibernate, glassfish startup very slow or memorry leak

719 views Asked by At

I'm using JavaEE7, hibernate-jpa2.1
My project have too many entity ( approximately 2000 entity)
If it only have 100 objects entity, it startup normal.
But now I've added all my business entity classes (2000) and I get a pergem space error.

 2016-12-29T11:40:36.903+0700|Severe: Exception in thread "DynamicReloader"
    2016-12-29T11:40:36.904+0700|Severe: java.lang.OutOfMemoryError: GC overhead limit exceeded
    2016-12-29T11:40:37.899+0700|Severe: Exception in thread "AutoDeployer"
    2016-12-29T11:40:37.900+0700|Severe: java.lang.OutOfMemoryError: GC overhead limit exceeded

I've improve jvm memory parameters but now my application is very slow during the start-up.
So, I would know if there are some option to load this entities faster ? Thank in advance

This is example entity

@Entity
@Table(name = "TBL_USER")
@NamedQueries({
        @NamedQuery(name = "TblUserO.findAll", query = "SELECT t FROM TblUserO t")
})
public class TblUserO implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "USER_ID", unique = true, nullable = false, precision = 11)
    private Long userId;

persistence.xml

     <persistence-unit name="c1spostgre1" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>jdbc/__PSG1</jta-data-source>
        <!-- Named JPQL queries per entity, but any other organization is possible -->
        <properties>
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
            <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
            <!-- <property name="hibernate.archive.autodetection" value="class" /> -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL92Dialect" />
            <property name="hibernate.jdbc.batch_size" value="20" />
            <property name="hibernate.order_updates" value="true"/>
            <property name="hibernate.order_inserts" value="true"/>
        </properties>
    </persistence-unit>
    <persistence-unit name="c1spostgre2" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>jdbc/__PSG2</jta-data-source>
        <properties>
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
            <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
            <!-- <property name="hibernate.archive.autodetection" value="class" /> -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL92Dialect" />
            <property name="hibernate.jdbc.batch_size" value="20" />
            <property name="hibernate.order_updates" value="true"/>
            <property name="hibernate.order_inserts" value="true"/>
        </properties>
    </persistence-unit>
2

There are 2 answers

0
OndroMih On

It seems that your application loads too much data from the database at startup. My guess is that the additional entities have too many eager relations and your application loads too much unnecessary data for what it needs to do.

I recommend to review the entity mappings and reduce as many relations to lazy as possible (especially *ToMany relations should all be lazily fetched, which is the default). In search of which unnecessary data is loaded, you can turn on logging of SQL queries to detect the SQL scripts used to laod the data. Your application might be loading all the entities from some tables into the memory, and filtering them later, which is not efficient.

You should reconsider to put filtering into the JPQL queries. You should also reduce usage of findAll queries, or at least limit the number of retrieved entities with setMaxResult() before calling getResultList().

0
Mike On

You have increased the heap memory (not permgen) enough so that your app can now start, but with so much needing to be loaded into memory you are almost certainly doing lots of garbage collection while all this gets loaded, which will cause the slowdown. It sounds like you need to do extensive performance tuning of your app, but that is very far outside the scope of a StackOverflow question.