gpt4 book ai didi

java - Servlet 发送旧版本的实体 (JPA)

转载 作者:行者123 更新时间:2023-12-01 09:27:08 26 4
gpt4 key购买 nike

当我向 Servlet 发出请求时,它会检查数据库中是否有任何更新的 Entities(我为此使用 JPA)。然后获取更新的 Entity,并且 Servlet 应该以 JSON 字符串的形式返回该实体。 但是我得到的是该实体的版本,该版本尚未更新 - 尽管我可以看到底层 MySQL 数据库已经有更新。 这怎么可能?我是否缺少任何缓冲区或缓存?

这是我的架构/数据流:

 ––––––--    timestamp of previous request   ----------–––
| client |–––––––––––––––––––––––––––––––––>| PullServlet |
-------- (e.g. 1475056871050) -------------
|(injected)
|
-------------------- ---------------
| Entity Facade |<----| remote |
| implementation | | Entity Facade |
-------------------- ---------------
|
@NamedQuery
| SELECT m
| FROM MyEntity m
| WHERE
| m.updated >=:previousRequest

假设 MySQL 数据库中的行如下所示:

 id | updated       | value
---+---------------+--------
12 | 0 | "hi"

然后进行更新,updated 列记录更新的时间(以毫秒为单位):

 id | updated       | value
---+---------------+--------
12 | 1475056872002 | "hello"

因此查询 SELECT ... WHERE 1475056872002 >= 1475056871050 返回实体,因为 updated 列 1 的值大于 previousRequest 参数。

但是当我记录查询结果时,我得到这样的结果

id=12, updated=0, value="hi"

而不是

id=12, updated=1475056872002, value="hello"

行被发送到我的Servlet,然后Servlet将版本作为JSON发送到我的客户端:

{
"id" : 12,
"updated" : 0,
"value" : "hi"
}

问题:是否有任何缓存可以“刷新”或其他任何内容,以确保所选行始终是最新的?

更新

所以我添加了一些日志记录,这就是结果:

外观进行更新

UPDATED entity: id=45111, updated=1475067494578, value=100 

客户端在几秒钟后向 servlet 发出请求

Client requested update – fetching entities  // servlet
Facade fetched update: id=45111, updated=1475066854564, value=96 // Facade
servlet received update: id=45111, updated=1475066854564, value=96 // servlet again

客户端接收 JSON

{
"id": 45111,
"updated": 1475066854564,
"value": 96
}

解决方案

感谢 Navneet Arora,我发现实体确实被缓存,并且查询使用了这些缓存的实例,而不是从数据库中检索实体。另一个问题中的 This Answer 显示了如何忽略缓存。

现在我的查询如下所示:

 TypedQuery<Post> query = getEntityManager().createNamedQuery("MyEntity.getUpdatedSince", MyEntity.class);
query.setParameter("previousRequest", previousRequest);
query.setHint(QueryHints.REFRESH, HintValues.TRUE); //this does the trick

现在一切都很好,我收到了所有更新:)

__________________
¹ updated 列和 previousRequest 参数是以毫秒为单位的 unix 时间戳

最佳答案

在您的调用代码中,您可以检查您的实体在缓存中是否可用。如果它具有较旧的值,您可以使用 evict 或 evictAll 方法清理它,然后尝试检索值。以下是一些示例编码语句供您引用:-

javax.persistence.Cache缓存=entityManagerFactory.getCache();

  System.out.println("cache.contain should return true if entity exists in cache: "+cache.contains(Order.class, order.Id())); 

使用以下代码,您可以从缓存中删除实体(如果存在):

            cache.evict(Order.class);

关于java - Servlet 发送旧版本的实体 (JPA),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39746592/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com