Search code examples
javaspringhibernatesessionlazy-initialization

Main Hibernate Session Closing automatically


I have a parent and child entities as below

@Entity
@Table(name = "PARENT")
public class Parent implements Comparable<Parent>, Serializable, Cloneable {

    private static final long serialVersionUID = 1584115734363172986L;

    public static final int NAME_LENGTH = 300;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "gen-seq")
    @GenericGenerator(name = "gen-seq", strategy = "native",
        parameters = {@Parameter(name = "sequence_name", value = "parent_id_seq")})
    private Long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    @BatchSize(size = 50)
    @SortNatural
    private SortedSet<Child> child = new TreeSet<>();
}

Child entity as below

@Entity
@Table(name = "Child")
@Inheritance(strategy= InheritanceType.JOINED)
public class Child implements Comparable<Object>, Serializable, Cloneable, Step<Child> {

    private static final long serialVersionUID = -9091312680432977997L;

    public static final int NAME_LENGTH = 255;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "gen-seq")
    @GenericGenerator(name = "gen-seq", strategy = "native",
        parameters = {@Parameter(name = "sequence_name", value = "child_id_seq")})
    private Long id;

    @ManyToOne()
    @JoinColumn(name = "parentId", nullable = false)
    private Parent parent;
}

I have configured Spring and Hibernate to process database operations, and to process Parent I have the following method added in the serviceimpl class.

public void processParent(final Long parentId, String userEmail) throws Exception {
getHibernateTemplate().execute(new HibernateCallback<Set<Void>>() {
    public void doInHibernate(Session session) throws HibernateException    {
        Parent parent = (Parent) session.get(Parent.class, parentId);           
        if (parent!=null && parent.getChild()!=null) {
            for (Child child: parent.getChild()) {

                // here the session is still Open when I call
                child.getParent();

                //But when I call this
                Parent p = getParent(child.getParent().getId());

                //now here the session got closed automatically, and now I cannot process the parent object

                }
            }
        }
    }
}}

In the above method, I have the session is opened until I call child.getParent() but if I call the below method which has another session itself which is not null, after returning the below method, then the session in above method is becoming null automatically.

public Parent getParent(final Long id) throws Exception {
Parent actionPoint = (Parent) getHibernateTemplate().execute(new HibernateCallback<Parent>() {

    /* (non-Javadoc)
    * @see org.springframework.orm.hibernate5.HibernateCallback#doInHibernate(org.hibernate.Session)
    */
    public Parent doInHibernate(Session session) throws HibernateException {
        Parent parent = (ActionPoint) session.get(Parent.class, id);

        //here also session is still open
        return parent;
    }
}}

Can anyone help me how to fix the main session should not be closed or become null. I know this is a configuration problem, but I don't know what should be configured.

Thanks in Advance, as I am trying to figure it out this issue for past 2 weeks.


Solution

  • You can add @Transactional above method and transaction will close at the end of the method. To enable @Transactional annotation you can add following code in your context-persistence.xml:

    <tx:annotation-driven transaction-manager="transactionManager" />
    
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <!-- Session Factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- <property name="configLocation" value="classpath:hibernate.cfg.xml"/> -->
        <property name="hibernateProperties">
            <map>
                <entry key="hibernate.default_schema" value="${database.default_schema}" />
                <entry key="hibernate.hbm2ddl.auto" value="${hibernate.hbm2ddl.auto}" />
                <entry key="show_sql" value="true" />
                <entry key="hibernate.dialect" value="${hibernate.dialect}" />
                <entry key="transaction.factory_class" value="org.hibernate.transaction.JDBCTransactionFactory" />
            </map>
        </property>
    </bean>