-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: LazyInitializationException
PostPosted: Sat Apr 07, 2007 3:22 pm 
Beginner
Beginner

Joined: Thu Feb 22, 2007 6:08 am
Posts: 35
Hi there
Im with a problem to retrieve a result from a list that is defined with a OneToMany relation. The code that raise the exception is the follow:
I have opened the session with the entityManager and a transaction. What am i forgeting to do? The problem is on the session or on the definition of the Entity? Can someone help me?

Im using Annotations to define the pojo's and the Sun JPA technology.

Hibernate version:
Hibernate Core 3.2.3
Hibernate EntityManager 3.3.1

Code:
Distrito selectedDistrito = (Distrito)distritosComboBox.getSelectedItem();
//cleaning the combo
clearConcelhosCombo();
EntityManagerFactory emf = HibernateUtil.getEntityManagerFactory();
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
List<Concelho> concelhos = selectedDistrito.getConcelhos();
           
for(Concelho aConcelho: concelhos){
    concelhosComboBox.addItem(aConcelho);
}
tx.commit();
em.close();


A "Distrito" is a divisory of a country in Portugal (like USA and the states)
A "Concelho" is a divisory of an "Distrito"

The Entity Distrito
Code:
@Entity
@Table(name="DISTRITOS")
public class Distrito implements Serializable {
    // <editor-fold defaultstate="collapsed" desc=" PrimaryKey:   String id ">
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id_distrito", nullable=false)
    private Long id;
   
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    //</editor-fold>
   
    // <editor-fold defaultstate="collapsed" desc=" Property:   String nome ">
    @Column(name="nome_distrito", nullable=false, unique=true)
    private String nome;
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    // </editor-fold>
   
    // <editor-fold defaultstate="collapsed" desc=" N-1  Relation to Pais pais ">
    @ManyToOne
    @JoinColumn(name="PAIS_FK", nullable=false)
    private Pais pais;
   
    public Pais getPais() {
        return this.pais;
    }
   
    public void setPais(Pais pais) {
        this.pais = pais;
    }
    // </editor-fold>
   
    // <editor-fold defaultstate="collapsed" desc=" 1-N  Relation to Collection /*Concelho*/ concelhos ">
    @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy="distrito")
    private List<Concelho> concelhos = new ArrayList<Concelho>();
   
    public List<Concelho> getConcelhos() {
        return this.concelhos;
    }
   
    public void setConcelhos(List<Concelho> concelhos) {
        this.concelhos = concelhos;
    }
   
    public void addConcelho(Concelho concelho){
        concelho.setDistrito(this);
        concelhos.add(concelho);
    }
    // </editor-fold>

    public String toString() {
        return getNome();
    }
}


The Entity Concelho
Code:
@Entity
@Table(name="CONCELHOS")
public class Concelho implements Serializable {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id_concelho", nullable=false)
    private Long id;
   
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @Column(name="nome_concelho", nullable=false, unique=true)
    private String nome;
   
    public String getNome() {
        return nome;
    }
   
    public void setNome(String nome) {
        this.nome = nome;
    }

    @ManyToOne
    @JoinColumn(name="DISTRITO_FK", nullable=false)
    private Distrito distrito;
   
    public Distrito getDistrito() {
        return this.distrito;
    }
   
    public void setDistrito(immo.persistence.Distrito distrito) {
        this.distrito = distrito;
    }

    @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy="concelho")
    private List<Freguesia> freguesias = new ArrayList<Freguesia>();
   
    public List<Freguesia> getFreguesias() {
        return this.freguesias;
    }
   
    public void setFreguesias(List<Freguesia> freguesias) {
        this.freguesias = freguesias;
    }
   
    public void addFreguesia(Freguesia freguesia){
        freguesia.setConcelho(this);
        freguesias.add(freguesia);
    }

    public String toString() {
        return getNome();
    }
   
}


Thanks a lot

--ms


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 6:00 pm 
Newbie

Joined: Sun Apr 09, 2006 4:57 pm
Posts: 10
Location: Milan (Italy)
Where do you find your Distrito? There is not any "read" from the database.

I think your code should be:

Distrito selectedDistrito = (Distrito)distritosComboBox.getSelectedItem();
//cleaning the combo
clearConcelhosCombo();
EntityManagerFactory emf = HibernateUtil.getEntityManagerFactory();
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

selectedDistrito = em.find(Distrito.class,selectedDistrito.getId());

List<Concelho> concelhos = selectedDistrito.getConcelhos();

for(Concelho aConcelho: concelhos){
concelhosComboBox.addItem(aConcelho);
}
tx.commit();
em.close();

I can't try. Does it solve?

Marco


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 8:04 pm 
Beginner
Beginner

Joined: Thu Feb 22, 2007 6:08 am
Posts: 35
it works thanks a lot!
But theres is something that i am not understanding.

The "Distritos" from the Country were getted from EAGER FetchType. Why the distritos were not associated with the persistence context like the country that was getted by an hql query? Why it was necessary to explicitly find it, once the country.getDistritos() brougth all the distritos?

Another question. Why the invocation of the distrito.getConcelhos() does not bring automaticly the elements? why the query to the DB is just made when we try to access something of the list?

Once again thanks alot

--ms


Last edited by mpsantos on Mon Apr 09, 2007 8:52 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 8:41 pm 
Newbie

Joined: Sun Apr 09, 2006 4:57 pm
Posts: 10
Location: Milan (Italy)
But in your code you were trying to read a "selectedDisitro.getConcelhos()" where selectedDisitros is not concerned to the Country, but to the selectedItem of a comboBox.

I have some difficult to understand your code as I have the Domain Model but only some sparse pieces of the "dynamic".

When you have a LazyInitializationException you always are in front at the fact that you are trying to navigate the associations of an object that, in the meantime, has become "detached" (or has never been persistent at all).

Look carefully at the code and, I'm sure, you'll find the solution.

Ciao
Marco


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 09, 2007 9:04 pm 
Beginner
Beginner

Joined: Thu Feb 22, 2007 6:08 am
Posts: 35
You were rigth,the object selectedDistrito was detached from the persistent context.

A Country(Pais in portuguese, eh eh eh) have 0..n Distritos;
Distrito: have 1 Country
0..n Concelhos

Concelho: have 1 Distrito
0..n Freguesias

Freguesias: have 1 Concelho

This is the model, how a Country is divided on Portugal.

The country automaticly get the Distritos from that country with the FetchType.EAGER, and then i have populated the comboBox. Why the "distritos" were not automaticly putted on the Persistence Context? Why do i have to get it exlicity with the em.find(...) method? Hope is more clearly. (sorry) In my tougth the selected distrito would be on the persistence(managed) state, but i am seeing that is not happening.

Another question. Why the invocation of the distrito.getConcelhos() does not bring automaticly the elements? why the query to the DB is just made when we try to access something of the list, like iterating or getting it's size?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 10, 2007 12:54 pm 
Newbie

Joined: Sun Apr 09, 2006 4:57 pm
Posts: 10
Location: Milan (Italy)
The Persistence Context is not something that exists outside the Entities and the Sessions.

You are probably working on a web or a swing application. So, probably, your code is something like this:

- open session
- read country (and eager fetched disitros)
- put the disitros in the combo
- close session --->> NOW THE COUNTRY IS DETACHED AND THE DISITROS ARE NOT REACHABLE ANYMORE, EVEN NOT PASSING THROUGH THE COUNTRY COLLECTION
- work at the front-end selecting from the combo the disitro
- open a new session
- use the selected disitro THAT IS NOT AVAILABLE ANYMORE
- ooops. LazyInitalizationException

These are very basics concepts working in Hibernate. I suggest you to read the chapters 9 of the "Java Persistence with Hibernate" book. If you buy the pdf version (and consult it or, better, study it) you spend 25$ and save hundred of hours fighting against "strange behaviours".

Believe me, I did the same mistakes you are doing, some time ago.

Marco


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.