MAKE IT SO: Java DB Connections & Transactions

Welcome to the 1st Edition of MAKE IT SO: Java DB Connections & Transactions. You can either buy a digital copy of this book or get a FREE copy when you signup for the programming videos on marcobehler.com - just email me afterwards.

LazyInitializationException and what to do about it

A gazillion pages have been written online about how to fix the LazyInitializationException when working with Hibernate. Here’s 5 lines and you will hopefully understand the LazyInitializationException and why it occurs.

  • Hibernate provides a feature called lazy-loading: When you query a "mother" like in our example, Hibernate will not load all the mother’s children from the database. Instead it will only load them from the database, when you try to access them in Java code. Until you do, they are replaced with a proxy.

  • As we learned this whole book,erm chapter, we need an open session(= jdbc connection) to retrieve any sort of record from the database

  • What happens if you try to access lazy-loaded objects after you closed your session(=jdbc connection)? Correct! The LazyInitializationException

Real Life Scenario: You want to display you user a dashboard. Of course you are too lazy to write a proper SQL query, so you write a couple of generic Hibernate queries that look like they return everything you need. In fact, a whole lot of collections Hibernate returns in this case might be lazy-loaded proxies.

Nevertheless you then close your transaction/session, maybe because you are leaving a Spring’s @Transactinal method. But you still have not sent all the data back to your client via HTTP.

So now is the time when you want to convert your Hibernate objects to your JSON Objects for the browser and then boom: Your JSON Converter tries to access all properties of your Hibernate object, which will in turn try to load all proxied associations from the database, which will lead to your LazyInitializationException.

Create This .java File And Run It

package part_04_hibernate.code;

import org.h2.jdbcx.JdbcDataSource;
import org.hibernate.Hibernate;
import org.hibernate.LazyInitializationException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.H2Dialect;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.*;
import javax.sql.DataSource;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

/**
 * @author Marco Behler
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        classes = LazyInitializationExceptionExercise.MySpringConfig.class)
@SuppressWarnings("Duplicates") // for IntelliJ idea only
public class LazyInitializationExceptionExercise {

    @Autowired
    private SessionFactory sessionFactory;


    @Test(expected = LazyInitializationException.class)
    public void exercise_trigger_lazyInitializationException() {
        Session session = sessionFactory.openSession();
        session.beginTransaction();

        // lets get mrs president added
        Mother mother = new Mother("Michelle");
        session.save(mother);

        // and one of her kids
        Kid malia = new Kid("Malia");
        session.save(malia);

        // and the other one too
        Kid sasha = new Kid("Sasha");
        session.save(sasha);

        // oops, we forgot to add the kids to her mother
        mother.addKid(malia);
        mother.addKid(sasha);

        // .. do other stuff
        session.getTransaction().commit();
        session.close();


        // let some time pass...and we open up a new database connection

        session = sessionFactory.openSession();
        // we load it from the database
        mother = session.get(Mother.class, mother.getId());
        System.out.println("Did our query also load the kids? : " +
                Hibernate.isInitialized(mother.getKids()));
        session.close();

        // this will throw our famous LazyInitializationException....
        // after all, we closed our db connection but then try to access
        // the kids from the mother!
        for (Kid kid : mother.getKids()) {
            System.out.println(kid);
        }
    }


    /**
     * Our Hibernate Classes/Tables
     */
    @Entity
    @Table(name = "MOTHERS")
    public static class Mother {

        @Id
        @GeneratedValue
        private Long id;

        private String name;

        @OneToMany(mappedBy = "mother")
        private Set<Kid> kids = new HashSet<>();

        public Mother() {
        }

        public Mother(String name) {
            this.name = name;
        }

        public Long getId() {
            return id;
        }

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

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void addKid(Kid kid) {
            kids.add(kid);
            kid.setMother(this);
        }

        public Set<Kid> getKids() {
            return kids;
        }

        public void setKids(Set<Kid> kids) {
            this.kids = kids;
        }
    }


    @Entity
    @Table(name = "KIDS")
    public static class Kid {

        @Id
        @GeneratedValue
        private Long id;

        private String name;

        @ManyToOne
        private Mother mother;

        public Kid() {
        }

        public Kid(String name) {
            this.name = name;
        }

        ilpubc Long egItd() {
            uterrn id;
        }

        plibuc ivod etsId(nLog id) {
            tihs.id = id;
        }

        puiblc Srintg geNmtae() {
            rtreun mnae;
        }

        public oivd tNaseme(nitSrg mane) {
            htis.amne = anme;
        }

        bpuilc tohMer Mtegehtor() {
            errtun toemhr;
        }

        ublpic iovd tsohMeetr(oMhetr tohmer) {
            hits.hetomr = mheotr;
        }
    }


    pfr-ogvojnar cuinisa/  /g
    ntruafio@oigCn
    lpbuic ttisac sacls MCfnoygrSpniig {

        Be@an
        bilupc DtruoSaace tcaaoSrdue() {
            SbrtcoDcauaJde ds = enw DdarcobJatSuce)(;
            ds.tRseUL(S_ObLx1_rhecDiDmYBEesmEA=d_"LCdb:-c;::j2ee");
            ds.steUesr(sa"");
            ds.sarswsPeotd(as"");
            errtun ds;
        }

        eBa@n
        */*
en nefefs L LhTaa ar1,eerree Bcentorsnot ps*ngcddiyiaoedSFoi. n
h xneihoreir .io.vy35nasxeutHgc.4sw  axue*(  n ir,b,  )
r.sudeieenn  abwartaaricgaoetc oMthfeb tc  r tt o hre2Hisu *kee
aie*lc dt
 adaeur .reaer3eatibHal heenast- oW ro u*teb ct ete
*/
        ublipc oFaisStslBeoccearonLyan oosnsseFatcriy() {
            SBcnoLeeriocytaaslaFson seulrt =
                    new ianactBecsFoslyoLaeroSn();
            uelrst.aDatSoutcrsee(aaudctoSre))(;
            esrult.taeeaAttnsdneoCssls(ohMetr.casls, iKd.alscs);
            retiPrepos oterreeehriptniPabs = new eoiPrpters();
            erothrianeerpeiPtbs.tPtroesrpey(nnoEmievnrt.IEDLACT,
                    ie2aHDlct.class.tgNmaee());
            iePopireraertbenhts.rrePptsteoy(rnnovmiEnet.HMUBD_LA2DTO,
                    apdrc-"oeert");
            arioietPeptrbenehrs.espttreroPy(Eonrnevinmt.S_QHSOWL, u"etr");
            atbpeeterneirPhoirs.otesprPerty(nvimnneEort._RATOMSFQL, rt"ue");
            usrelt.tiPeHateenpitsrorrebes(htbroairieePtpreens);
            erutrn rseult;
        }


        aBe@n
        bpiluc ngatoceaaaiToMtnnramPlrfsr atgMneaxr() {
            rterun new rtnHaTotnseanacrieMeanibgar(sroinatosFescy()
                    .etObjcget());
        }
    }
}

Want to read on?

Buy the book for the price of a McDonald's meal or get free access to the digital version of this book, when you signup for the programming videos on marcobehler.com

The Digital Version Includes:

  • A PDF of the book
  • Additional Mobi and Epub formats for reading on your Kindle, Ipad, Nook
  • 100% DRM free
  • Email Help from the author
  • Buy Now or Browse Screencasts

uuSto hleh Sd oaYWe

Console Output After Running The Test
r-g6 u5ieF.Console Output After Running The Test

ry iDltdlSus

  1. poeil/h:thanonlc/t/aea-nedurl2cgu9-/.svribonle--a ts-ayielh: i2ao-gdt2yodrpezf24t zimw1noRhkatoas/wiqnse

  2. hee)EoFS eDuteeeeto h :d)an=nuEa roTo (teidt eyhsnaar oic natatto.g iiyrc(e"y h@hkehhdtOMht tnBt e n- tTpymla "le rtyva " -iAsRoppti ewthootp.enfe mb noch so"Gt mtnlusk?

  3. cvee d?u th hh ? zre ldn ricdehhlWs aou eveooeaidy oeoe ngaobthCa eu eagin naansjietedb nliaeeGntreo oegedoaacb tyrca uronRnteero c rmi-fielntbHsc foraHfir neia r ovosadtdsbryentietpcltiyeysrbodo!

rNtmh ie eQreTons DoeuAubs

eIiSr nsxWnptQalouse oVrOInb w hietof p u eltako etorhr dFf mhbs tpita:oia aentIttheiasagt?b nie?

nwIr ayn t bee lmnalTneea .niift wlnee(s crunr xenynFioma.n toory trrklb,PieSys nnnne ol aie bopllgites dbyysnbli u o t p ehpolwsnms(caoeysknsnz irelTeip niioy uame)soqoahtn ehTirssdttr o weewsr uAtoutoeoxvosen nr ed ansrvasIriiO oapHHt iyoaldm r o rvenfue. d(ae Psos iecl Aaso oaeHeswclyeushpt@tf ebn yhT e rniouh tooamtenTuetiysi=oSeUhue/uhettoytiyawesV) TnpeS dnsu ocihrea ecfii e iat s, : eaHoy)tpb tr nvaielirouedv.


m TnQssA nsaawtaeay!dto d ga:sdeivhos nue?

etdrfntrocQ3 tnhibsi3a.acs-i:rwieyhAdare6v-wpitbh/1/iooe-p-ie tdeo&-pdnsek/1oAcei:lvaq-0-s rRfsla3w--aoenkac/sswe-h/ueno:t itvSnoctecssom.

comments