Spring boot data jpa @Query 本机查询的单元测试用例是否可行?
Is it possible for unit test cases for Spring boot data jpa @Query native queries?
我有一个配置了 JPA 的 spring 启动应用程序。在查询数据库时,我在 spring data @query 注释的帮助下 运行 本机 sql 查询。现在我打算使用 spring 启动测试框架编写测试用例。能不能写测试?
代码:
String searchQuery = "SELECT dh1.* FROM device_hist AS dh1 JOIN (" +
"SELECT rank() OVER (PARTITION BY dh.device_nm, dh.lst_log_in_user_id ORDER BY lst_chkin_ts DESC), " +
"dh.device_nm, dh.lst_log_in_user_id, dh.lst_chkin_ts FROM device_hist dh) AS T ON dh1.device_nm = T.device_nm " +
"AND dh1.lst_log_in_user_id = T.lst_log_in_user_id AND dh1.lst_chkin_ts = T.lst_chkin_ts WHERE T.rank = 1 AND " +
"dh1.lst_chkin_ts >= :lst_chkin_ts ";
String searchCountQuery = "SELECT count(*) FROM device_hist AS dh1 JOIN (" +
"SELECT rank() OVER (PARTITION BY dh.device_nm, dh.lst_log_in_user_id ORDER BY lst_chkin_ts DESC), " +
"dh.device_nm, dh.lst_log_in_user_id, dh.lst_chkin_ts FROM device_hist dh) AS T on h1.device_nm = T.device_nm " +
"AND dh1.lst_log_in_user_id = T.lst_log_in_user_id AND dh1.lst_chkin_ts = T.lst_chkin_ts WHERE T.rank = 1 " +
"AND dh1.lst_chkin_ts >= :lst_chkin_ts ";
@Query(value = searchQuery + "ORDER BY dh1.device_nm, dh1.lst_chkin_ts DESC",
countQuery = searchCountQuery,
nativeQuery = true)
Page<DeviceHistory> findAllLatestDeviceHistoryBylastCheckInTimeStamp(
@Param("lst_chkin_ts") Date lastCheckInTimeStamp, Pageable pageable);
测试用例:
@Test
void testfindAllLatestDeviceHistoryBylastCheckInTimeStamp() {
LocalDate localDateTime = LocalDate.now();
ZoneId defaultZoneId = ZoneId.systemDefault();
Instant instant = localDateTime.minusDays(10).atStartOfDay(defaultZoneId).toInstant();
Date timeStamp = Date.from(instant);
Page<DeviceHistory> devices = deviceHistoryRepository.findAllLatestDeviceHistoryBylastCheckInTimeStamp(timeStamp, pageable);
assertNotNull(devices.getContent());
}
错误:
无法提取结果集; SQL[n/a];嵌套异常是 org.hibernate.exception.SQLGrammarException: 无法提取结果集
org.springframework.dao.InvalidDataAccessResourceUsageException: 无法提取结果集; SQL[n/a];嵌套异常是 org.hibernate.exception.SQLGrammarException: 无法提取结果集
在 org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:281)
在 org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
在 org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
在 org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
在 org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
在 org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149)
在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
在 org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
在 com.sun.proxy.$Proxy138.findAllLatestDeviceHistoryBylastCheckInTimeStamp(来源不明)
在 com.aexp.de.crypto.wde.server.repository.DeviceHistoryRepositoryTest.testfindAllLatestDeviceHistoryBylastCheckInTimeStamp(DeviceHistoryRepositoryTest.java:158)
在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在 java.lang.reflect.Method.invoke(Method.java:498)
在 org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
在 org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
...
在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
... 96 更多
原因:org.postgresql.util.PSQLException:错误:缺少 table“h1”
的 FROM 子句条目
我认为你有问题
String searchCountQuery
Exception 告诉您您遇到了一个名为 h1
table
的问题
ERROR: missing FROM-clause entry for table "h1"
据我所知,这个字符串包含 h1
:
"dh.device_nm, dh.lst_log_in_user_id, dh.lst_chkin_ts FROM device_hist dh) AS T on h1.device_nm = T.device_nm”。 (我猜应该是dh1)
通常,如果您遇到 SQLGrammarException: could not extract ResultSet
,那么可能是您的 SQL 有问题。此外,堆栈跟踪的其余部分通常有助于澄清问题。
我有一个配置了 JPA 的 spring 启动应用程序。在查询数据库时,我在 spring data @query 注释的帮助下 运行 本机 sql 查询。现在我打算使用 spring 启动测试框架编写测试用例。能不能写测试?
代码:
String searchQuery = "SELECT dh1.* FROM device_hist AS dh1 JOIN (" +
"SELECT rank() OVER (PARTITION BY dh.device_nm, dh.lst_log_in_user_id ORDER BY lst_chkin_ts DESC), " +
"dh.device_nm, dh.lst_log_in_user_id, dh.lst_chkin_ts FROM device_hist dh) AS T ON dh1.device_nm = T.device_nm " +
"AND dh1.lst_log_in_user_id = T.lst_log_in_user_id AND dh1.lst_chkin_ts = T.lst_chkin_ts WHERE T.rank = 1 AND " +
"dh1.lst_chkin_ts >= :lst_chkin_ts ";
String searchCountQuery = "SELECT count(*) FROM device_hist AS dh1 JOIN (" +
"SELECT rank() OVER (PARTITION BY dh.device_nm, dh.lst_log_in_user_id ORDER BY lst_chkin_ts DESC), " +
"dh.device_nm, dh.lst_log_in_user_id, dh.lst_chkin_ts FROM device_hist dh) AS T on h1.device_nm = T.device_nm " +
"AND dh1.lst_log_in_user_id = T.lst_log_in_user_id AND dh1.lst_chkin_ts = T.lst_chkin_ts WHERE T.rank = 1 " +
"AND dh1.lst_chkin_ts >= :lst_chkin_ts ";
@Query(value = searchQuery + "ORDER BY dh1.device_nm, dh1.lst_chkin_ts DESC",
countQuery = searchCountQuery,
nativeQuery = true)
Page<DeviceHistory> findAllLatestDeviceHistoryBylastCheckInTimeStamp(
@Param("lst_chkin_ts") Date lastCheckInTimeStamp, Pageable pageable);
测试用例:
@Test
void testfindAllLatestDeviceHistoryBylastCheckInTimeStamp() {
LocalDate localDateTime = LocalDate.now();
ZoneId defaultZoneId = ZoneId.systemDefault();
Instant instant = localDateTime.minusDays(10).atStartOfDay(defaultZoneId).toInstant();
Date timeStamp = Date.from(instant);
Page<DeviceHistory> devices = deviceHistoryRepository.findAllLatestDeviceHistoryBylastCheckInTimeStamp(timeStamp, pageable);
assertNotNull(devices.getContent());
}
错误:
无法提取结果集; SQL[n/a];嵌套异常是 org.hibernate.exception.SQLGrammarException: 无法提取结果集 org.springframework.dao.InvalidDataAccessResourceUsageException: 无法提取结果集; SQL[n/a];嵌套异常是 org.hibernate.exception.SQLGrammarException: 无法提取结果集 在 org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:281) 在 org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255) 在 org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528) 在 org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) 在 org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) 在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) 在 org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) 在 org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) 在 com.sun.proxy.$Proxy138.findAllLatestDeviceHistoryBylastCheckInTimeStamp(来源不明) 在 com.aexp.de.crypto.wde.server.repository.DeviceHistoryRepositoryTest.testfindAllLatestDeviceHistoryBylastCheckInTimeStamp(DeviceHistoryRepositoryTest.java:158) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675) 在 org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) ...
在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366) 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) 在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ... 96 更多 原因:org.postgresql.util.PSQLException:错误:缺少 table“h1”
的 FROM 子句条目我认为你有问题
String searchCountQuery
Exception 告诉您您遇到了一个名为 h1
table
ERROR: missing FROM-clause entry for table "h1"
据我所知,这个字符串包含 h1
:
"dh.device_nm, dh.lst_log_in_user_id, dh.lst_chkin_ts FROM device_hist dh) AS T on h1.device_nm = T.device_nm”。 (我猜应该是dh1)
通常,如果您遇到 SQLGrammarException: could not extract ResultSet
,那么可能是您的 SQL 有问题。此外,堆栈跟踪的其余部分通常有助于澄清问题。