Hibernate Lazy Mode doesn't work with Spring Boot

I created Spring boot Application with JPA, I have two entity classes( Account , Instance ). my entity classes look like below. this configurations are working well. but doesn’t working Hibernate Lazy Loading. anyone’s can help me please.

my English not good. i know my explanations is not good. sorry about that.

@Entity
@Table(name = "accounts")
public class Account extends Base {

private static final long serialVersionUID = 1L;
@Column(name = "name")
private String name;
  @OneToMany(mappedBy = "account", cascade = CascadeType.REMOVE, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<Instance> instances = new HashSet<>();

... getters() and Setters()...
}

@Entity
@Table(name = "instances")
public class Instance extends Base {
private static final long serialVersionUID = 1L;

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

@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "account_id")
@JsonIdentityReference(alwaysAsId = true)
private Account account;

... getters() and Setters()...
}

Most likely it’s due to the default Open Session in View antipattern employed by Spring Boot. Check out this StackOverflow answer for more details about deactivating OSIV.

1 Like

Thank you so much! i think lazy mode is working now. but after this implementation i got this error.

2018-Oct-18 10:09:48.245 WARN  [http-nio-8080-exec-3] o.s.w.s.m.s.DefaultHandlerExceptionResolver - Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: dev.model.Account.instances, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: dev.model.Account.instances, could not initialize proxy - no Session (through reference chain: dev.model.Account["instances"])

Check out this article for more details about how you should handle the LazyInitializationException.

1 Like

thank you! ill read this article. :slightly_smiling_face:

hello, @vlad
I read above your link and i enabled ‘ibernate.enable_lazy_load_no_trans: true’ , its working well. thank you! but still load Account With all Instances. ( look like lazy doesn’t work )

  jpa:
    open-in-view: false
    properties:
      hibernate.enable_lazy_load_no_trans: true

It’s a bad idea that you activated that property. It’s worse than Open Session in View.

1 Like

@vlad , oh really. i understand!, ill remove it. I’m beginner (Spring boot & JPA ). so what can i do for it? ( for above i mentioned error )

You need to use a JPQL query with JOIN FETCH the lazy associations.

1 Like

@vlad , I wrote query for it. but still i have Lazy loading problem. fetching all Instances with Account.

@Repository
public interface AccountRepository extends BaseJpaRepository<Account> {

    @Query("select c from Account c join fetch c.instances where c.id = :id")
    Account getAccount(@Param("id") UUID id);
}

Since you said you were a beginner, you need to read the entire Hibernate User Guide first. Not only that you will fix this issue, but many others that you would bump into if you don’t read the documentation.

i understand ill do it first!

Yeah make sure to read the entire guide before you start.Or else u will be facing multiple errors in future.

Hi @bhagyaperera123

I faced this same issue. This entity fetch lazy type doesn’t work with Spring Boot and Spring Data Jpa, unless you do what @vlad says about the projection, or using @JsonIgnore annotation in those relations you don’t want to fetch :slight_smile:

Just for you to know, with Spring Data Rest, this fetch type is working well.

Cheers

1 Like

Need some confirmation, Have to go with disable the property

spring.jpa.open-in-view=false

or use custom query.(If I go with this then for further data I have to create other rest api with link. is it so?)

It’s up to you if you like lazy loading in the “representation layer” or not. The Spring team decided that open-in-view should be true by default because they think it’s ok. Not sure what you mean by “… have to create other rest api with link…”.

Hi Question , isn’t the lazy fetchType made to not load the child entity?

If I use the jpql query with join fetch, I get the entity but… that’s not what I want eft

I would hope to load parent entity without loading the child entity using fetchType.Lazy but saying that it is not the case, or is it my knowledge that is wrong

Well, if you join fetch an association then Hibernate will “join” the table for it and “fetch” (select) the data of it. If you don’t want to load the association, then simply remove the join fetch.

thanks sorry for last reply :slight_smile:

Hi Beikov,
but…why fetch = FetchType.LAZY don’t work ?
Those that you say is correct, if we use jpql, but if I don’t want use it, why the fetchtype in OneToMany annotation dont give us the right result ?