Question

I'm wondering: What is the point of FetchType.LAZY in one(many)-to-many using DAO Pattern? It is basically useless? As soon as you are outside of your DAO (eg. were the actual work is done) you can't fetch the related data as you are not in a hibernate session anymore.

Lets make an Example:

Student and Class. A student takes many classes. he now logs into the system and his Student entity object is retrieved from the system.

application layer -> Service Layer -> DAO

Now the Student wants to see which classes he takes and oops a LazyInitializationException occurs as we are outside of DAO.

What are the options to prevent this? I've like googled hours and not found a solution for this except to actually fetch everything before leaving the DAO which defeats the purpose of lazy in the first place. (Have read about OpenSessionViewFilter but this should work independent of the application layer)

How do you solve this issue in a good way? What are alternative patterns that don't suffer from this?

EDIT:

I get no LazyInitializationException with following settings:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.compound", 
        cascade = CascadeType.ALL, orphanRemoval = true)
@Fetch(FetchMode.JOIN)

Funny thing is it must be exactly like this.

removing @Fetch -> LazyInitializationException

Even stranger is if I remove orphanRemoval = true, then LazyInitializationException also occurs even with @Fetch. So both of those are required.

Maybe someone could enlighten me why this is the case. Currently I'm tending to ditch hibernate completely as with pure JDBC I would have reached the desired behavior hours ago...

Was it helpful?

Solution

You can always fetch foreign-key relation data without the same ession. Since your session does not exists outside your Application Layer you just fetch it manually in the method where you retrieve the data and set it.

Application Layer:

public List<SchoolClass> getSchoolClassesByStudent(Serializable identifier)
{
    List<SchoolClasses> schoolClasses = // get classes by student using criteria or hql
    return schoolClasses;
}

Client Layer:

public void loadSchoolClassesByStudent(Student student)
{
    student.setSchoolClasses(application.getSchoolClassesByStudent(student.getId()));
}

I myself choosed not to support any collections in my hibernate entities.
I fetch all child relations with very generic methods that my server provides to my client similar to this one.

Edit: Or create some logic (interceptor?) that can check outside the DAO if data is uninitialized before accessing it and initialize it using a generic method.
This would also assume that Hibernate jar's are on the client level, which depends if this is a good idea (Same if the uninitialized data is not set to null).

OTHER TIPS

One way to solve the problem is to use OpenSessionInViewFilter Filter.

<filter>
    <filter-name>hibernateSessionFilter</filter-name>
    <filter-class>
        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
</filter>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top