Difference between FetchType LAZY and EAGER in Java Persistence API?
Asked Answered
B

18

742

What is the difference between FetchType.LAZY and FetchType.EAGER in Java Persistence API?

Bosket answered 7/6, 2010 at 15:28 Comment(1)
EAGER loading of collections means that they are fetched fully at the time their parent is fetched. While EAGER loading, then all my child is fetched. The child is fetched in the PersistentSet and PersistentList (or PersistentBag), inside the Persistent Bag , it displayed as an Array List. Is it correct??..Gus
E
1423

Sometimes you have two entities and there's a relationship between them. For example, you might have an entity called University and another entity called Student and a University might have many Students:

The University entity might have some basic properties such as id, name, address, etc. as well as a collection property called students that returns the list of students for a given university:

A university has many students

public class University {
   private String id;
   private String name;
   private String address;
   private List<Student> students;

   // setters and getters
}

Now when you load a University from the database, JPA loads its id, name, and address fields for you. But you have two options for how students should be loaded:

  1. To load it together with the rest of the fields (i.e. eagerly), or
  2. To load it on-demand (i.e. lazily) when you call the university's getStudents() method.

When a university has many students it is not efficient to load all of its students together with it, especially when they are not needed and in suchlike cases you can declare that you want students to be loaded when they are actually needed. This is called lazy loading.

Here's an example, where students is explicitly marked to be loaded eagerly:

@Entity
public class University {

    @Id
    private String id;

    private String name;

    private String address;

    @OneToMany(fetch = FetchType.EAGER)
    private List<Student> students;

    // etc.    
}

And here's an example where students is explicitly marked to be loaded lazily:

@Entity
public class University {

    @Id
    private String id;

    private String name;

    private String address;

    @OneToMany(fetch = FetchType.LAZY)
    private List<Student> students;

    // etc.
}
Emilieemiline answered 7/6, 2010 at 15:53 Comment(9)
@BehrangSaeedzadeh can you list some practical differences, or the advantages and disadvantages of each type of loading (other than the efficiency you mentioned). Why would one want to use eager loading?Pillbox
@Pillbox In order for lazy loading to work, the JDBC session must still be open when the target entities want to be loaded into the memory by invoking the getter method (e.g. getStudents()), but sometimes this is not possible, because by the time this method is called, the session is already closed and the entity detached. Similarly, sometimes we have a client/server architecture (e.g. Swing client/JEE server) and the entities/DTOs are transferred over the wire to the client and again most often in these scenarios lazy loading won't work due to the way the entities are serialized over the wire.Bushman
I'd like to add some more info to this answer from my book - To save memory, Lazy loading is generally used for one to many and many to many relationships. For one to one, generally Eager is used.Ouachita
In lazy loading, when I call the getStudents() method for the first time, are the results cached? so that I could access those results faster next time?Shanonshanta
@Shanonshanta depends if you enable the second level cache (enabled by default)Tibold
@BoratSagdiyev that is bad advice IMHO(the eager loading you mention I mean). Use lazy everywhere and in JQL, fetch eagerly when you need to. Why? well, I keep running into system that are loading 6 joins because ToOne's are all eager. In fact, I want the old hibernate lazy default back. You never know your use-cases ahead of time and one will need lazy and another eager...instead use lazy everywhere and when you need eager, create a query for it.Illuminance
@BoratSagdiyev This more clearly states why you should never use EAGER... vladmihalcea.com/2014/12/15/eager-fetching-is-a-code-smell perfect read.Illuminance
If you don't use eager, how/ when do you close the session? Jaws DB for instance only gives 10 connections on their free tier and slightly more on expensive paid tiers, do this too is an issue). Fortunately my use case- blockchain one to many blocks is well suited to eagerWickman
What changes might using fetch type as EAGER or LAZY put on deleting the entity. Let's say we want to delete one student of the university when we have used FetchType.EAGER on @OneToMany private List<Student> students; in University class. I notice that deleteById method of JpaRepository is unable to delete. I found a person having similar issue here: - #67150943 Solved by using LAZY.Richter
V
386

Basically,

LAZY = fetch when needed
EAGER = fetch immediately
Vie answered 7/6, 2010 at 15:31 Comment(0)
S
87

EAGER loading of collections means that they are fetched fully at the time their parent is fetched. So if you have Course and it has List<Student>, all the students are fetched from the database at the time the Course is fetched.

LAZY on the other hand means that the contents of the List are fetched only when you try to access them. For example, by calling course.getStudents().iterator(). Calling any access method on the List will initiate a call to the database to retrieve the elements. This is implemented by creating a Proxy around the List (or Set). So for your lazy collections, the concrete types are not ArrayList and HashSet, but PersistentSet and PersistentList (or PersistentBag)

Soileau answered 7/6, 2010 at 15:54 Comment(5)
I used that concept in fetching the details of a child entity, but I can not see any difference between them. When I specify Eager fetch, It fetches everything and When I debug it, I see "Bean deferred" at the child entity. When I say course.getStudents(), it fires an SQL query( saw that on console). In Lazy fetch type also, same thing happens. So, What's is the difference??Pacheco
eager collections are fetched when the owning entity is loaded. Lazy collections are fetched when you access them. If this is not the behaviour your saw, there was probably something wrong with your environment (e.g. running old versions of a class)Soileau
@Soileau You specified lazy loading of collections only . Can a simple string field be lazy loaded?Theomachy
No. You need to use a query or a different mapped entity to get a subset of the columnsSoileau
@Bozho, hey can you please answer this then if it's set on fetchtype = LAZY the default one even if try to get the collection with the getter hibernete throws an error telling me it can't evaluateJohannajohannah
E
27

The main difference between the two types of fetching is a moment when data gets loaded into a memory.
I have attached 2 photos to help you understand this.

Eager fetch
 Eager fetch

Lazy fetch Lazy fetch

Encumbrancer answered 25/5, 2020 at 8:27 Comment(0)
P
20

I may consider performance and memory utilization. One big difference is that EAGER fetch strategy allows to use fetched data object without session. Why?
All data is fetched when eager marked data in the object when session is connected. However, in case of lazy loading strategy, lazy loading marked object does not retrieve data if session is disconnected (after session.close() statement). All that can be made by hibernate proxy. Eager strategy lets data to be still available after closing session.

Porett answered 29/1, 2013 at 2:39 Comment(1)
Yes and it crashed my app until I switched to eager. I suppose session management is an art and science itself but JawsDB gives 10 connections on free tier and not much more on paid tiers.Wickman
Q
15

By default, for all collection and map objects the fetching rule is FetchType.LAZY and for other instances it follows the FetchType.EAGER policy.
In brief, @OneToMany and @ManyToMany relations does not fetch the related objects (collection and map) implicictly but the retrieval operation is cascaded through the field in @OneToOne and @ManyToOne ones.

(courtesy :- objectdbcom)

Quixote answered 22/7, 2013 at 13:21 Comment(0)
C
14

The Lazy Fetch type is by default selected by Hibernate unless you explicitly mark Eager Fetch type. To be more accurate and concise, difference can be stated as below.

FetchType.LAZY = This does not load the relationships unless you invoke it via the getter method.

FetchType.EAGER = This loads all the relationships.

Pros and Cons of these two fetch types.

Lazy initialization improves performance by avoiding unnecessary computation and reduce memory requirements.

Eager initialization takes more memory consumption and processing speed is slow.

Having said that, depends on the situation either one of these initialization can be used.

Coppage answered 14/5, 2017 at 14:24 Comment(3)
The statement that it "does not load the relationships unless you invoke it via the getter method" is important to note, and also a pretty retarded design decision in my opininion… I just encountered a case where I assumed it would fetch it upon access and it didn't, because I didn't excplicitly call a getter function for it. By the way, what constitutes a "getter" function? Will JPA defer loading the property until a function called getMember is called that exactly matches the member's name pattern?Mayst
@Mayst can you explain a little bit in more depth this staement does not load the relationships unless you invoke it via the getter method. I got confused while implementing a many to many relation I removed the getter for other entity from the owning side and then tried Lazy and eager fetching. And i found no difference.Satyriasis
Hard to recall since it was 5 years since I last worked with it, but given my comment I guess it means that it for some reason didn't actually load the values of the linked object by default, and that when I tried using one of them I instead just got the datatype default value. My suspicion is that I in some member function must have accessed member variables or functions of the linked object directly and not gotten what I expected - leading to obscure and hard to debug issues. Sorry I couldn't be of more help. :)Mayst
C
12

Both FetchType.LAZY and FetchType.EAGER are used to define the default fetch plan.

Unfortunately, you can only override the default fetch plan for LAZY fetching. EAGER fetching is less flexible and can lead to many performance issues.

My advice is to restrain the urge of making your associations EAGER because fetching is a query-time responsibility. So all your queries should use the fetch directive to only retrieve what's necessary for the current business case.

Chemo answered 9/11, 2014 at 7:31 Comment(2)
"EAGER fetching is less flexible and can lead to many performance issues." ... A truer statement is "Using or not using EAGER fetching can lead to performance problems". In that particular case when a lazily initialized field is expensive to access AND infrequently used, lazy fetching will benefit performance. But, in the case when a variable is frequently used, lazy initialization can actually degrade performance by requiring more trips to the database than eager initialization. I would suggest applying FetchType correctly, not dogmatically.Snowslide
Are you promoting your book here!!. But yes I feel it depends on the use case, and the object size being referred to in the cardinality relationship.Mamey
L
11

As per my knowledge both type of fetch depends your requirement.

FetchType.LAZY is on demand (i.e. when we required the data).

FetchType.EAGER is immediate (i.e. before our requirement comes we are unnecessarily fetching the record)

Letdown answered 11/3, 2014 at 12:20 Comment(0)
B
10

I want to add this note to what was said above.

Suppose you are using Spring (MVC and Data) with this simple architect:

Controller <-> Service <-> Repository

And you want to return some data to the front-end if you are using FetchType.LAZY, you will get a LazyInitializationException after you return data to the controller method since the session is closed in the Service so the JSON Mapper Object can't get the data.

There are two common options to solve this problem, depending on the design, performance, and developer:

  1. The easiest one is to use FetchType.EAGER or any other Anti-patterns solutions, So that the session will still be alive at the controller method, but these solutions will impact the performance.
  2. The best practice is to use FetchType.LAZY with a mapper (like MapStruct) to transfer data from Entity to another data object DTO and then send it back to the controller, so there is no exception if the session closed.

There is a simple example:

@RestController
@RequestMapping("/api")
public class UserResource {

    @GetMapping("/users")
    public Page<UserDTO> getAllUsers(Pageable pageable) {
        return userService.getAllUsers(pageable);
    }
}

@Service
@Transactional
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional(readOnly = true)
    public Page<UserDTO> getAllUsers(Pageable pageable) {
        return userRepository.findAll(pageable).map(UserDTO::new);
    }
}

@Repository
public interface UserRepository extends JpaRepository<User, String> {

    Page<User> findAll(Pageable pageable);
}

public class UserDTO {

    private Long id;

    private String firstName;

    private String lastName;

    private String email;
    
    private Set<String> addresses;

    public UserDTO() {
        // Empty constructor needed for Jackson.
    }

    public UserDTO(User user) {
        this.id = user.getId();
        this.firstName = user.getFirstName();
        this.lastName = user.getLastName();
        this.email = user.getEmail();
        this.addresses = user.getAddresses().stream()
            .map(Address::getAddress)
            .collect(Collectors.toSet());
    }

    // Getters, setters, equals, and hashCode
}

@Entity
@Table(name = "user")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String firstName;

    @Column
    private String lastName;

    @Column(unique = true)
    private String email;
    
    @OneToMany(mappedBy = "address", fetch = FetchType.LAZY)
    private Set<Address> addresses = new HashSet<>();

    // Getters, setters, equals, and hashCode
}

@Entity
@Table(name = "address")
public class Address implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String address;

    @ManyToOne
    @JsonIgnoreProperties(value = "addresses", allowSetters = true)
    private User user;

    // Getters, setters, equals, and hashCode
}
Brien answered 1/7, 2019 at 12:22 Comment(2)
Could you pls give an example on how to implement the 3rd solution, e.g. in @Behrang's answer?Avatar
@Naik, I have updated the answer and added an example.Brien
B
6

From the Javadoc:

The EAGER strategy is a requirement on the persistence provider runtime that data must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed.

E.g., eager is more proactive than lazy. Lazy only happens on first use (if the provider takes the hint), whereas with eager things (may) get pre-fetched.

Barnyard answered 7/6, 2010 at 15:31 Comment(5)
what do you mean by "first use"?Bosket
@leon: Say you have an entity with an eager field and a lazy field. When you get the entity, the eager field will have been loaded from the DB by the time you receive the entity reference, but the lazy field may not have been. It would be fetched only when you tried to access the field via its accessor.Barnyard
@T.J. Crowder, what's the default when no fetchtype defined ?Inseverable
@MahmoudSaleh: I have no idea. It probably varies based on something. I haven't used JPA in a real project so I haven't gotten into the guts of it.Barnyard
@MahmoudS: Default fetchtypes: OneToMany: LAZY, ManyToOne: EAGER, ManyToMany: LAZY, OneToOne: EAGER, Columns : EAGERGoldenseal
E
5

JOIN is the big deal

Take it in easy way :

assume we have a class called User and another class called an Address and suppose each user have one or more addresses that mean relationship (one-to-many) here if you execute :

FetchType.LAZY execute sql command like without join :

SELECT * FROM users 

FetchType.EAGER execute sql command like within join :

SELECT * FROM users u join address a on a.user_id = u.user_id

Note : the above queries just for clarify image for you but Hibernate framework in realty execute similar queries of above quires .

Which Fetch Types is Better?

  • Since Eager fetching loads ALL relationships automatically, It's a big performance hog
  • Lazy fetching doesn't load any relationships unless told to, which leads to better performance
  • Eager fetching makes for easier programming, since less code is required
  • Lazy loading could lead to bugs (exceptions) If the entire system Isn't properly tested
  • All things considered, you should still prefer Lazy loading over Eager, as it's more performant

If you are using Spring Boot Framework so going to application.properties file and add the below command to know what exactly going on .

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Earn answered 9/3, 2021 at 10:59 Comment(0)
C
3

Book.java

        import java.io.Serializable;
        import javax.persistence.Column;
        import javax.persistence.Entity;
        import javax.persistence.GeneratedValue;
        import javax.persistence.GenerationType;
        import javax.persistence.Id;
        import javax.persistence.ManyToOne;
        import javax.persistence.Table;

        @Entity
        @Table(name="Books")
        public class Books implements Serializable{

        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="book_id")
        private int id;
        @Column(name="book_name")
        private String name;

        @Column(name="author_name")
        private String authorName;

        @ManyToOne
        Subject subject;

        public Subject getSubject() {
            return subject;
        }
        public void setSubject(Subject subject) {
            this.subject = subject;
        }

        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getAuthorName() {
            return authorName;
        }
        public void setAuthorName(String authorName) {
            this.authorName = authorName;
        }

        }

Subject.java

    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue; 
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;

    @Entity
    @Table(name="Subject")
    public class Subject implements Serializable{

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="subject_id")
    private int id;
    @Column(name="subject_name")
    private String name;
    /**
    Observe carefully i have mentioned fetchType.EAGER. By default its is fetchType.LAZY for @OneToMany i have mentioned it but not required. Check the Output by changing it to fetchType.EAGER
    */

    @OneToMany(mappedBy="subject",cascade=CascadeType.ALL,fetch=FetchType.LAZY,
orphanRemoval=true)
    List<Books> listBooks=new ArrayList<Books>();

    public List<Books> getListBooks() {
        return listBooks;
    }
    public void setListBooks(List<Books> listBooks) {
        this.listBooks = listBooks;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    }

HibernateUtil.java

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {

 private static SessionFactory sessionFactory ;
 static {
    Configuration configuration = new Configuration();
    configuration.addAnnotatedClass (Com.OneToMany.Books.class);
    configuration.addAnnotatedClass (Com.OneToMany.Subject.class);
    configuration.setProperty("connection.driver_class","com.mysql.jdbc.Driver");
    configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate");                                
    configuration.setProperty("hibernate.connection.username", "root");     
    configuration.setProperty("hibernate.connection.password", "root");
    configuration.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
    configuration.setProperty("hibernate.hbm2ddl.auto", "update");
    configuration.setProperty("hibernate.show_sql", "true");
    configuration.setProperty(" hibernate.connection.pool_size", "10");
    configuration.setProperty(" hibernate.cache.use_second_level_cache", "true");
    configuration.setProperty(" hibernate.cache.use_query_cache", "true");
    configuration.setProperty(" cache.provider_class", "org.hibernate.cache.EhCacheProvider");
    configuration.setProperty("hibernate.cache.region.factory_class" ,"org.hibernate.cache.ehcache.EhCacheRegionFactory");

   // configuration
    StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
    sessionFactory = configuration.buildSessionFactory(builder.build());
 }
public static SessionFactory getSessionFactory() {
    return sessionFactory;
}
} 

Main.java

    import org.hibernate.Session;
    import org.hibernate.SessionFactory;

    public class Main {

    public static void main(String[] args) {
        SessionFactory factory=HibernateUtil.getSessionFactory();
        save(factory);
        retrieve(factory);

    }

     private static void retrieve(SessionFactory factory) {
        Session session=factory.openSession();
        try{
            session.getTransaction().begin();
            Subject subject=(Subject)session.get(Subject.class, 1);
            System.out.println("subject associated collection is loading lazily as @OneToMany is lazy loaded");

            Books books=(Books)session.get(Books.class, 1);
            System.out.println("books associated collection is loading eagerly as by default @ManyToOne is Eagerly loaded");
            /*Books b1=(Books)session.get(Books.class, new Integer(1));

            Subject sub=session.get(Subject.class, 1);
            sub.getListBooks().remove(b1);
            session.save(sub);
            session.getTransaction().commit();*/
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            session.close();
        }

        }

       private static void save(SessionFactory factory){
        Subject subject=new Subject();
        subject.setName("C++");

        Books books=new Books();
        books.setAuthorName("Bala");
        books.setName("C++ Book");
        books.setSubject(subject);

        subject.getListBooks().add(books);
        Session session=factory.openSession();
        try{
        session.beginTransaction();

        session.save(subject);

        session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            session.close();
        }
    }

    }

Check the retrieve() method of Main.java. When we get Subject, then its collection listBooks, annotated with @OneToMany, will be loaded lazily. But, on the other hand, Books related association of collection subject, annotated with @ManyToOne, loads eargerly (by [default][1] for @ManyToOne, fetchType=EAGER). We can change the behaviour by placing fetchType.EAGER on @OneToMany Subject.java or fetchType.LAZY on @ManyToOne in Books.java.

Cynic answered 30/4, 2016 at 4:46 Comment(0)
S
3

The best way to understand the difference between these is if you understand lazy-okay. FetchType.LAZY tells hibernate to only fetch related entities from the database when you use the relationship.

P.S: In many projects I have worked on, I have seen that many software developers do not pay attention to them, and there are even those who call themselves senior.If the project you're working on isn't data-exchanging on large volumes of data, it's okay to have EAGER here. However, considering the problems where n+1 problems may occur, you need to pay attention to these after you know the fetch types of the relations by default.

Here you can see the default values: Default fetch type for one-to-one, many-to-one and one-to-many in Hibernate

Also, it doesn't end there, even after understanding fetching types. To understand when to use LAZY and when to use EAGER, you also need to understand the concepts of unidirectional and bidirectional. Also, the spring boot repository has some methods that allow it to read data for you lazy or eager.For example, the getOne() or getById() methods allow you to lazy fetch data from entities.In short, what you use and when depends on what the other party wants you to do.

Senescent answered 1/3, 2022 at 5:49 Comment(0)
T
1

public enum FetchType extends java.lang.Enum Defines strategies for fetching data from the database. The EAGER strategy is a requirement on the persistence provider runtime that data must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed. The implementation is permitted to eagerly fetch data for which the LAZY strategy hint has been specified. Example: @Basic(fetch=LAZY) protected String getName() { return name; }

Source

Terbia answered 29/8, 2016 at 16:10 Comment(0)
S
0

@drop-shadow if you're using Hibernate, you can call Hibernate.initialize() when you invoke the getStudents() method:

Public class UniversityDaoImpl extends GenericDaoHibernate<University, Integer> implements UniversityDao {
    //...
    @Override
    public University get(final Integer id) {
        Query query = getQuery("from University u where idUniversity=:id").setParameter("id", id).setMaxResults(1).setFetchSize(1);
        University university = (University) query.uniqueResult();
        ***Hibernate.initialize(university.getStudents());***
        return university;
    }
    //...
}
Supranational answered 6/3, 2014 at 9:6 Comment(0)
E
0

LAZY: It fetches the child entities lazily i.e at the time of fetching parent entity it just fetches proxy(created by cglib or any other utility) of the child entities and when you access any property of child entity then it is actually fetched by hibernate.

EAGER: it fetches the child entities along with parent.

For better understanding go to Jboss documentation or you can use hibernate.show_sql=true for your app and check the queries issued by the hibernate.

Exertion answered 1/4, 2017 at 4:23 Comment(0)
C
0

There is one tiny comment: If you use lazy type, if you close session you will not able to fetch data from database later(See Output below).

But with Eager type, you fetch data while you fetching Instructor, so after session.close() you will be able to use/show these courseList data.

  @OneToMany(//fetch = FetchType.EAGER, 
        fetch = FetchType.LAZY,  
           mappedBy = "instructor",        
           cascade = {CascadeType.DETACH, CascadeType.MERGE,
                CascadeType.PERSIST, CascadeType.REFRESH})
private List<Course> courseList; 

I would suggest try both of them in debug mode. In this case, I use lazy type as you can see.

 try {
        //start the transaction
        session.beginTransaction();

        //Get instructor from database
        int instructorId = 7;

        Instructor tempInstructor = session.get(Instructor.class,instructorId);

        System.out.println("Instructor: "+tempInstructor);


        //commit transaction
        session.getTransaction().commit();

       //close session
       session.close();

       //since courselist is lazy loaded... this should fail
       //so in here we are not able to fetch courselist data
       //get courses
        System.out.println("Courses "+tempInstructor.getCourseList() );


        System.out.println("Done!");

    } finally {
        session.close();
        factory.close();
    }
}

Output Exception:

Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.exercise.hibernate.entity.Instructor.courseList, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:621)
at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
at java.base/java.lang.StringConcatHelper.simpleConcat(StringConcatHelper.java:408)
at com.exercise.hibernate.main.EagerLazyLoading.main(EagerLazyLoading.java:56)
Crayon answered 25/9, 2022 at 23:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.