Home > Enterprise >  An unexpected SQLSelectCountMismatchException occurs
An unexpected SQLSelectCountMismatchException occurs

Time:09-02

I have been complaining about that I must check hibernate queries with my eyes without automation. That's why I am fascinated by the library called db-util by vladmihalcea.

But here is the problem. I am unable to use its methods. I use Kotlin Spring Boot. Below are codes.

Entity

@Entity
class Book(
    @Id
    @GeneratedValue(strategy = IDENTITY)
    val id: Long = 0L,
)

Repository

interface BookRepository : JpaRepository<Book, Long>

Service

@Service
class DemoService(
    private val bookRepository: BookRepository,
) {
    @Transactional
    fun a() {
        bookRepository.findById(0)
    }
}

Finally, test code

@SpringBootTest
@TestConstructor(autowireMode = ALL)
internal class DemoServiceTest(
    private val demoService: DemoService,
) {
    @Test
    fun a() {
        reset()
        demoService.a()
        assertSelectCount(1)
    }
}

This test gives me a failing result with the message below:

Expected 1 statements but recorded 0 instead!
com.vladmihalcea.sql.exception.SQLSelectCountMismatchException: Expected 1 statements but recorded 0 instead!

What I don't understand is that, the service method a() under test is transactional one but the assertSelectCount() method does not detect the query having been executed.

Here are the logs:

[    Test worker] org.hibernate.SQL                        : select book0_.id as id1_0_0_ from book book0_ where book0_.id=?
[    Test worker] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [0]

Could you please help me? Thanks in advance.

CodePudding user response:

It was data proxy that I missed.

Below codes are needed to pass the test method a(). I have found this here.

@Component
class DatasourceProxyBeanPostProcessor : BeanPostProcessor {
    override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any {
        return bean
    }

    override fun postProcessAfterInitialization(bean: Any, beanName: String): Any {
        return if (bean is DataSource) {
            ProxyDataSourceBuilder.create(bean)
                .logQueryBySlf4j(INFO)
                .multiline()
                .countQuery()
                .build()
        } else bean
    }
}
  • Related