Как использовать FindAllBy с несколькими полями в JpaRepository? - PullRequest
0 голосов
/ 19 марта 2019

Ниже вы можете найти минимальный пример, показывающий мою проблему:

src/main/kotlin/com/mytest/findallbytest/Application.kt:

package com.mytest.findallbytest

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class MyTestApplication

fun main(args: Array<String>) {
    runApplication<MyTestApplication>(*args)
}

src/main/kotlin/com/mytest/findallbytest/model/Thing.kt:

package com.mytest.findallbytest.model

import org.springframework.data.jpa.domain.AbstractPersistable
import javax.persistence.Entity
import javax.persistence.Table

@Entity
@Table(name = "things")
class Thing(
        val foo: Long,
        val bar: Long
) : AbstractPersistable<Long>()

src/main/kotlin/com/mytest/findallbytest/repository/ThingRepository.kt:

package com.mytest.findallbytest.repository

import com.mytest.findallbytest.model.Thing
import org.springframework.data.jpa.repository.JpaRepository

interface ThingRepository : JpaRepository<Thing, Long> {
    fun findAllByFooAndBar(foos: Iterable<Long>, bars: Iterable<Long>): Iterable<Thing>
}

src/main/resources/application.yml:

spring:
  datasource:
    url: jdbc:h2:mem:db;MODE=PostgreSQL

src/main/resources/db/migration/V1__things.sql:

CREATE SEQUENCE HIBERNATE_SEQUENCE;

CREATE TABLE things (
    id      BIGINT PRIMARY KEY NOT NULL,
    foo     BIGINT NOT NULL,
    bar     BIGINT NOT NULL
);

src/test/kotlin/com/mytest/findallbytest/FullTest.kt:

package com.mytest.findallbytest

import com.mytest.findallbytest.model.Thing
import com.mytest.findallbytest.repository.ThingRepository
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension

@ExtendWith(SpringExtension::class)
@SpringBootTest
class FullTest {

    @Autowired
    lateinit var repo: ThingRepository

    @Test
    fun `basic entity checks`() {
        repo.save(Thing(1, 2))
        repo.save(Thing(3, 4))
        repo.save(Thing(1, 4))
        assertThat(repo.findAll()).hasSize(3)

        // ERROR: Expected size:<2> but was:<0>
        assertThat(repo.findAllByFooAndBar(listOf(1L, 3L), listOf(2L, 4L))).hasSize(2)
    }
}

Проблемаis, findAllByFooAndBar возвращает пустой список.Тем не менее, я ожидаю этого, поэтому верните первые две из трех сохраненных сущностей.

Что я делаю неправильно, и как может быть достигнута моя цель или запрос нескольких сущностей, совпадающих по нескольким полям?

Ответы [ 2 ]

1 голос
/ 19 марта 2019
fun findAllByFooInAndBarIn(foos: Iterable<Long>, bars: Iterable<Long>): Iterable<Thing>
0 голосов
/ 23 марта 2019

Одно (не очень хорошее) решение - вручную создать запрос и использовать EntityManager для его отправки:

@Repository
class SecondThingRepository(private val entityManager: EntityManager) {
    fun selectByFoosAndBars(foosAndBars: Iterable<Pair<Long, Long>>): Iterable<Thing> {
        val pairsRepr = foosAndBars.joinToString(prefix = "(", postfix = ")") { "(${it.first}, '${it.second}')" }
        val query: TypedQuery<Thing> = entityManager.createQuery("SELECT t FROM Thing t WHERE (t.foo, t.bar) IN $pairsRepr", Thing::class.java)
        return query.resultList
    }
}

А потом:

repo2: SecondThingRepository
...
assertThat(repo2.selectByFoosAndBars(listOf(Pair(1L, 2L), Pair(3L, 4L)))).hasSize(2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...