Description
Hi, I'm writing an interface projection and instead of getting some readable error while initializing the result I'm getting a runtime NullPointerException on non-nullable type.
@Entity
class Customer(
@Id
val id: Long? = null,
var name: String? = null,
val age: Int
)
interface CustomerRepository : CrudRepository<Customer, Int> {
@Query("select c.name from Customer c")
fun customProjectionQuery(): List<NameWithAgeOnly>
}
interface NameWithAgeOnly {
val name: String
val age: Int
}
@Service
class Service(
private val customerRepository: CustomerRepository
) {
@PostConstruct
fun test() {
val customerWithName = Customer(id = 1, name = "John", age = 25)
val customerWithoutName = Customer(id = 2, name = null, age = 33)
customerRepository.save(customerWithName)
customerRepository.save(customerWithoutName)
val customers = customerRepository.customProjectionQuery()
for (customer in customers) {
println(customer.name)
}
}
}
Caused by: java.lang.NullPointerException: Cannot invoke "org.dev.NameWithAgeOnly.getName()" because "customer" is null
Can you please clarify what am I doing wrong. And maybe give some workaround. Isn't it a bug?
I've also tried to use kotlin dto class instead of interface, but then I'm getting
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [org.dev.NameWithAgeOnly]
Here is reproducible example: https://github.com/iPave/jpa-projections-issue/tree/main