Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does FetchType.LAZY not work in Hibernate/JPA?

I ve got the following object (simplified):

@Entity
@Table(name = "delivery_addresses")
data class DeliveryAddress (
        val street: String
) {

    @ManyToOne(fetch=FetchType.LAZY)
    lateinit var user: User
}

and when I query the object by ID

val deliveryAddress = deliveryAddressService.findById(1)

which does

override fun findById(deliveryAddressId: Long): DeliveryAddress? {
    return deliveryAddressRepository.findById(deliveryAddressId).orElse(null) // JpaRepository
}

I can see the following queries are executed:

select deliveryad0_.street as street6_2_0_, deliveryad0_.user_id as user_id8_2_0_, from delivery_addresses deliveryad0_ where deliveryad0_.id=?

select user0_.id as id1_5_0_, user0_.email as email2_5_0_, user0_.password as password3_5_0_, where user0_.id=?

How can I make FetchType.LAZY work as excepted (also @Basic(fetch = FetchType.LAZY) is not working for me)?

like image 299
mleister Avatar asked May 31 '20 12:05

mleister


1 Answers

Finally I was able to figure it out. The issue is related to kotlin data classes (see KT-28525)

One should not use data classes with spring-data-jpa. Referenced from kotlin spring-guide

Here we don’t use data classes with val properties because JPA is not designed to work with immutable classes or the methods generated automatically by data classes. If you are using other Spring Data flavor, most of them are designed to support such constructs so you should use classes like data class User(val login: String, …​) when using Spring Data MongoDB, Spring Data JDBC, etc.

In order to make lazy fetching working as expected, entities should be open. My solution:

build.gradle.kts:

plugins {
  kotlin("plugin.allopen") version "1.3.61"
}

allOpen {
  annotation("javax.persistence.Entity")
  annotation("javax.persistence.Embeddable")
  annotation("javax.persistence.MappedSuperclass")
}
like image 118
mleister Avatar answered Oct 03 '22 05:10

mleister