Search code examples
springspring-dataspring-data-rest

Weird issue in Lazy load


I am totally confused with one issue Spring data + hibernate

We have a Restful service which we are migrating to V2.

So the old controller looks like

@Api(tags = {"assignments"})
@RestController
@CheckedTransactional
public class AssignmentListController {

  @Inject
  private AssignmentListService assignmentListService;

  //REST function
  public list() {....}
}

The REST function list calls AssignmentListService to load assignments, which is a collection, and loads some data lazily. Its works excellent.

What I did is I copied this controller as name AssignmentListControllerV2, and it looks like

@Api(tags = {"assignments"})
@RestController
@CheckedTransactional
public class AssignmentListControllerV2 {
  @Inject
  private AssignmentListService assignmentListService;

  @Inject
  private AssignmentDtoMapper assignmentDtoMapper;

  public list() {...}
}

The code is same except AssignmentDtoMapper bean added, which is created using MapStruct.

Now the problem, When I call this new service, somehow I get a Lazy Load exception. The error is

could not initialize proxy - no Session

I desperately need some help as I have no clue whats happening. I have just copied the code in a new class and its failing.


Solution

  • The exception is actually pretty clear, Hibernate can't load the lazy fetched member because there is no persistence context open when you hit it.

    I suppose that in the V2 the:

    @Inject
    private AssignmentDtoMapper assignmentDtoMapper;
    

    is to change some JPA business entity into DTO? It's probably the source of the exception if you try to map not loaded member there.

    If you want to avoid the exception on unitiliazed proxy you can try something like

    public boolean isProxyInitialized(Object obj){
        if(obj instanceof HibernateProxy){
            HibernateProxy proxy = (HibernateProxy) obj;
    
            return !proxy.getHibernateLazyInitializer().isUninitialized();
        }
    
        return obj != null;   
    }
    

    It should return true if the member as bean fetched otherwise false.