【发布时间】:2017-03-08 16:54:11
【问题描述】:
我想使用 Spring-Data-JPA(Hibernate 实现)和 QueryDSL(类型安全)从表“product”中查找最后插入的项目以生成 SQL:SELECT * FROM product ORDER BY id DESC LIMIT 1
我使用 @Transactional 从 Service 调用 findLast() 并希望 setLockMode(LockModeType.PESSIMISTIC_WRITE) 并在此 SQL 查询中添加“SELECT .. FOR UPDATE”。
public class ProductRepositoryImpl extends QueryDslRepositorySupport implements ProductRepositoryCustom {
public ProductRepositoryImpl() {
super(Product.class);
}
//SELECT * FROM PRODUCTS ORDER BY ID DESC LIMIT 1
@Override
public Product findLast() {
QProduct product = QProduct.product;
return from(product).orderBy(product.id.desc()).limit(1L).fetchOne();
}
}
这是生成的 SQL
Hibernate: select * from ( select product0_.id as id11, product0_.description as description21, product0_.price as price31, product0_.productStatus as productStatus41, product0_.quantity as quantity51 from PRODUCTS product0 order by product0.id desc ) where行数
问题:在扩展 org.springframework.data.jpa.repository.support.QueryDslRepositorySupport 的存储库中添加 setLockMode() 的最佳方法是什么?
我已经尝试过了,但它返回 Object 并且需要转换(产品):
getQuerydsl().createQuery(product)
.setLockMode(LockModeType.PESSIMISTIC_WRITE).orderBy(product.id.desc()).limit(1L).fetchOne();
【问题讨论】:
-
从生成的 SQL 来看,似乎并没有忽略限制,只是它使用了数据库的内部 rownum 语义来返回
rownum <= 1的所有行跨度> -
是的,但是在子查询中执行,这不能与使用“SELECT .. FOR UPDATE”锁定选定的行一起工作,我检查了如果我跳过 limit() 生成的 SQL 是相同的 rownum
-
如果指定
limit()并告诉它调用fetch()或fetchResults()会怎样。生成的 SQL 是否按预期工作? -
我的错,它是 Oracle 数据库,并且限制按预期工作。
标签: hibernate spring-data-jpa querydsl