使用 JPQL createQuery 时返回的旧数据
使用 JPA/Eclipse TopLink。
我正在更新一个表(使用 createNativeQuery),如下所示:
Query query = em.createNativeQuery("UPDATE Products SET productName='" + p.getProductName() + "',productVendor='" + p.getProductVendor() + "',productDescription='" + p.getProductDescription() + "',quantityInStock=" + p.getQuantityInStock() + ",buyPrice =" + p.getBuyPrice() + ",msrp=" + p.getMsrp() + " WHERE productCode='" + p.getProductCode() + "'");
query.executeUpdate();
更新反映在数据库(MySQL)中
用于检索(使用 createQuery),如下所示:
Query query1 = em.createQuery("SELECT p from Products p where p.productCode='"+searchTerm+"'");
return query1.getResultList();
但是,返回的 ResultList 始终是更新之前的数据。但是当我使用 createNativeQuery 而不是 createQuery 时,会返回最新更新的数据。 createQuery 方法可能出现什么错误?
Using JPA/Eclipse TopLink.
I'm updating a table (using createNativeQuery) as shown below:
Query query = em.createNativeQuery("UPDATE Products SET productName='" + p.getProductName() + "',productVendor='" + p.getProductVendor() + "',productDescription='" + p.getProductDescription() + "',quantityInStock=" + p.getQuantityInStock() + ",buyPrice =" + p.getBuyPrice() + ",msrp=" + p.getMsrp() + " WHERE productCode='" + p.getProductCode() + "'");
query.executeUpdate();
The update is reflected in the DB (MySQL)
For retrieving (using createQuery) as show below:
Query query1 = em.createQuery("SELECT p from Products p where p.productCode='"+searchTerm+"'");
return query1.getResultList();
However, the ResultList returned is always the data before the update. But when I use the createNativeQuery instead of createQuery the latest updated data is returned. What could the possible error be with createQuery method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您使用批量更新或本机查询时,您将绕过一级缓存。 Toplink 无法知道其一级缓存中已有的实体已更改。因此,必须清除实体管理器,以便查询返回刷新的对象。
但最好的方法可能是首先避免批量更新。您的第一个查询可以替换为 JPQL 查询,该查询使用给定代码加载产品,然后简单地更新 Product 实体。即使您保留更新查询,它也可以用 JPQL 而不是 SQL 编写(但您仍然会遇到问题)。
最后,您的查询应该使用参数来避免注入并确保所有内容都正确转义:
when you use batch update or native queries, you're bypassing the first-level cache. Toplink has no way to know that the entities it already has in its first-level cache have been changed. So the entity manager must be cleared in order for the query to retrurn refreshed objects.
But the best way is probably to avoid batch updates in the first place. Your first query could be replaced by a JPQL query that loads the product with the given code, and then simply updates the Product entity. Even if you keep the update query, it could be written in JPQL rather than SQL (but you would still have the problem you're having).
Finally, your queries should use parameters to avoid injections and make sure everything is properly escaped: