Spring Boot JPA Projection of Entity with Postgresql JSON field as Map<Key, Value>

1.1k views Asked by At

I'm using Spring Boot with Kotlin and PostgreSQL as DB. For JSON fields I use hibernate-types-52:

dependencies {
    ...
    implementation("com.vladmihalcea:hibernate-types-52:2.10.2")
    ...
}

I have an entity Address with street JSON field:

@Entity
@Table(name = "addresses")
@TypeDefs(
  TypeDef(name = "jsonb", typeClass = JsonBinaryType::class),
  TypeDef(name = "json", typeClass = JsonStringType::class),
)
data class Address(

  @Id
  var id: Int? = null,

  @Type(type = "jsonb")
  @Column(name = "street", columnDefinition = "json", nullable = false)
  var street: Map<Language, String>,
    
  @Column(name = "zip_code" nullable = false)
  var zipCode: String,

  @Column(name = "created_at", nullable = false, updatable = false)
  @CreationTimestamp
  var createdAt: Date? = null,

  @Column(name = "updated_at", nullable = false)
  @UpdateTimestamp
  var updatedAt: Date? = null,
}

Corresponding repository is:

@Repository
interface AddressRepository : JpaRepository<Address, Int> {

    fun findStreetByZipCode(zipCode: String): AddressStreetOnly?
}

Where AddressStreetOnly is an interface:

interface AddressStreetOnly {
    val id: Int
    val street: Map<Language, String>
}

and Language is an enumeration enum class Language { EN, RU, KZ, TJ }

The problem is when I call findStreetByZipCode the underlying SQL statement has all fields in the select query:

select
    address0_.id as id1_9_,
    address0_.created_at as created_2_9_,
    address0_.street as street3_9_,
    address0_.updated_at as updated4_9_,
    address0_.zip_code as zip_cod5_9_
from
    addresses
where
    address0_.zip_code = ?

But if I change val street: Map<Language, String> type in the AddressStreetOnly interface to val street: Any, everything works as expected:

select
    address0_.id as col_0_0_,
    address0_.street as col_1_0_
from
    addresses
where
    address0_.zip_code = ?

I think the problem is in the type of the street field which is Map and it's the Map is forcing to fetch all the fields of the entity. How can I fix this?

0

There are 0 answers