如何使用 querydsl 测试更新?
Posted
技术标签:
【中文标题】如何使用 querydsl 测试更新?【英文标题】:How can I test update using querydsl? 【发布时间】:2022-01-06 21:31:24 【问题描述】:我正在尝试使用带有 querydsl 的自定义存储库来测试更新。 但它失败了,因为数据没有更新。我在调用存储库函数后尝试刷新,但它不起作用。 我认为这与某种实体管理器问题有关,但由于我是 Spring 新手,所以我不太清楚。
存储库代码:
@Override
public Long updateNotice(String noticeId, Notice noticeInfo)
UpdateClause<JPAUpdateClause> updateBuilder = queryFactory.update(notice);
if(StringUtils.isNotEmpty(noticeInfo.getTitle()))
updateBuilder.set(notice.title, noticeInfo.getTitle());
if(StringUtils.isNotEmpty(noticeInfo.getContents()))
updateBuilder.set(notice.contents, noticeInfo.getContents());
if(StringUtils.isNotEmpty(noticeInfo.getTheme()))
updateBuilder.set(notice.theme, noticeInfo.getTheme());
if (StringUtils.isNotEmpty(Integer.toString(noticeInfo.getState())))
updateBuilder.set(notice.state, noticeInfo.getState());
if(StringUtils.isNotEmpty(noticeInfo.getLocation()))
updateBuilder.set(notice.location, noticeInfo.getLocation());
updateBuilder.set(notice.startDate, noticeInfo.getStartDate());
updateBuilder.set(notice.endDate, noticeInfo.getEndDate());
updateBuilder.set(notice.modiDate, LocalDateTime.now());
Long count = updateBuilder
.where(notice.noticeId.eq(noticeId))
.execute();
return count;
测试代码:
@Test
public void updateNoticeTest()
//given
Notice titleNotice = Notice.builder()
.title("Update notice")
.startDate(LocalDateTime.of(2021, 10, 11, 00, 00, 00))
.endDate(LocalDateTime.of(2021, 12, 12, 00, 00, 00))
.build();
List<Notice> notices = noticeRepository.findAll();
String id = notices.get(1).getNoticeId();
Notice notice = notices.get(1);
log.info(notice.toString());
//when
Long result = noticeRepository.updateNotice(id, titleNotice);
noticeRepository.flush();
//then
Notice res = noticeRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("No such notice with id " + id));
log.info(res.toString());
assertThat(res.getTitle()).isEqualTo("Update notice");
测试配置:
# Datasource settings
spring.datasource.url=jdbc:h2:mem:testdb;Mode=Oracle;DB_CLOSE_DELAY=-1
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# set jpa
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
#logging.level.org.hibernate.type.descriptor.sql=trace
# set log
logging.level.root=info
# set page option
# 1-based
spring.data.web.pageable.one-indexed-parameters=true
# page size = 10
spring.data.web.pageable.default-page-size=10
spring.data.web.pageable.max-page-size=1000
【问题讨论】:
【参考方案1】:刷新没有帮助,因为它将EntityManager
收集的更改写入数据库。但是 EM 没有收集任何更改,因为您使用了更新语句,它不会更新基本上是 EM 的一级缓存。
findById
将通过一些较早的交互返回已经在一级缓存中的旧实例,可能是首先存储它们。
为了解决这个问题,你应该调用EntityManager.clear
清空一级缓存
【讨论】:
以上是关于如何使用 querydsl 测试更新?的主要内容,如果未能解决你的问题,请参考以下文章
直接从querydsl更新数据时如何刷新Spring JPA?