Hibernate hangs or throws lazy initialization no session or session was closed

后端 未结 3 2210
面向向阳花
面向向阳花 2021-02-12 14:54

I\'m enhancing an old Spring/Hibernate application and im stuck. I have a method that reads a file 3000+ lines long, each line has a record which has to be compared with somethi

3条回答
  •  不要未来只要你来
    2021-02-12 15:35

    You're getting a lazy initialization exception because your session is being closed before you access Product's member variables. When the following line is executed:

    Product product= (Product) super.find(Product.class, id)
    

    Hibernate opens a sessions, retrieves what you're looking for, then closes then session. Any fields that have lazy=true are not retrieved at this time; instead, these fields are populated by proxies. When you try to retrieve the actual value of proxied object, it will attempt to go back to the database using the active session to retrieve the data. If no session can be found, you get the exception that you're seeing. Setting lazy=true has advantages because it prevents the entire object graph from being loaded immediately; nested objects are left alone until you specifically ask for them.

    There are two common techniques to deal with your problem. The first you've already identified, which is setting lazy=false. This is fine if a product always has product attributes, and you typically use a product and it's attributes together. If you often need just the Product object without its attributes, you're creating unnecessary database load.

    The second technique is to mark a method as transactional using Spring annotations.

    @Transactional
    public Product find(Integer id) throws DataAccessException {
    
    }
    

    A few notes:

    1. You need some additional configuration for transactions to work (the @Transactional annotation isn't enough). See here for more information.
    2. Best practices dictate that you annotate methods in your service layer, rather than your data access layer.

提交回复
热议问题