# Value class + spring + JPA @Query

**URL:** <https://discuss.kotlinlang.org/t/value-class-spring-jpa-query/24107>\
**Category:** Support\
**Created:** [February 4, 2022, 12:00pm UTC](https://discuss.kotlinlang.org/t/value-class-spring-jpa-query/24107 "2022-02-04T12:00:17Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mstawick](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mstawick/32/6124_2.png) [@mstawick](https://discuss.kotlinlang.org/u/mstawick)\
**Post date:** [February 4, 2022, 12:00pm UTC](https://discuss.kotlinlang.org/t/value-class-spring-jpa-query/24107/1 "2022-02-04T12:00:17Z")

</div>

Having this piece of code (simplified):

Value class:

```auto
@JvmInline
value class Foo(val value: String)

```

Entity:

```auto
@Entity
class Bar {
  @Id
  var id: Long = 0L
  var foo: Foo = Foo("")
}

```

Repository:

```auto
interface BarRepository : JpaRepository<Bar, Long> {

  @Query("select b from Bar b where b.foo = :foo")
  fun findByFoo(foo: Foo): List<Bar>

  @Query("select b from Bar b where b.foo in (:fooList)")
  fun findByFooIn(fooList: List<Foo>): List<Bar>
}

```

The first query will work, but the other one will fail with JPA complaining that it was expecting a list of String-s, but got a list of Foo-s.

If I change the signature so that fooList becomes List (and map input to list of strings) it works, but of course, then I will lose type checking.

My question is why does it work with a single item, but fails with a list, and if anyone is aware of a workaround (other than using strings explicitly).

---

<div class="post-metadata">

**Author:** ![lobodpav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lobodpav/32/10717_2.png) [@lobodpav](https://discuss.kotlinlang.org/u/lobodpav)\
**Post date:** [January 22, 2024, 1:39pm UTC](https://discuss.kotlinlang.org/t/value-class-spring-jpa-query/24107/2 "2024-01-22T13:39:39Z")

</div>

Did you find any satisfactory answer? The same problem happens when you need to return a `Set` of `Foo`.

---

<div class="post-metadata">

**Author:** ![madmax1028](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/madmax1028/32/3335_2.png) [@madmax1028](https://discuss.kotlinlang.org/u/madmax1028)\
**Post date:** [January 22, 2024, 7:44pm UTC](https://discuss.kotlinlang.org/t/value-class-spring-jpa-query/24107/3 "2024-01-22T19:44:12Z")

</div>

As long as you don’t use any additional invariants in your type I would recommend using aliases instead. Kotlin’s value classes don’t work so well in Java-originated libraries and technologies because of boxing issue.

Another advice for you would be to separate JPA model from your business model, REST model, etc. Then you could stick to value classes anywere as long as you map them once from a database model.

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [January 23, 2024, 5:34am UTC](https://discuss.kotlinlang.org/t/value-class-spring-jpa-query/24107/4 "2024-01-23T05:34:29Z")

</div>

This is just a guess, not an actual answer.

My guess is that because `Foo` is used as the type parameter of a `List`, the compiler might be overlooking it for the inline replacement. I wonder if you could decompile the JVM Bytecode to Java code and see what that interface looks like.

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [January 23, 2024, 5:42am UTC](https://discuss.kotlinlang.org/t/value-class-spring-jpa-query/24107/5 "2024-01-23T05:42:52Z")

</div>

Ok I think it’s this thing: [Inline value classes | Kotlin Documentation](https://kotlinlang.org/docs/inline-classes.html#representation)

If I’m understanding it correctly, in places where the value class is used directly, it’s replaced with the real type. But in places where a generic is used, the value class is used instead of the real type, I think.
