【问题标题】:Spring JpaRepository is not returning updated data [duplicate]Spring JpaRepository 没有返回更新的数据[重复]
【发布时间】:2014-06-13 21:25:05
【问题描述】:

我正在开发一个基于 Spring 的服务器。我有两个 Controllers 正在监听不同的 http 请求。它们都有一个变量引用相同的 Repository@Autowired 注释。

@Controller
public class ClientController {
    @Autowired
    NodeRepository nodeRepository;
    ...
}

@Controller
public class NodeController {
    @Autowired
    NodeRepository nodeRepository;
    ...
}

所有数据库操作都使用NodeRepository:

public interface NodeRepository extends JpaRepository<Node, Long>{
    Node findByNodeId(long nodeId);
    List<Node> findByStatusIn(Set<String> status);
    List<Node> findByNodeIdIn(Set<Long> ids);
    Node findByPhoneNumber(String phoneNumber);
    Node findByCloudId(String cloudId);
    Node findByDeviceDescription(String deviceDescription);
}

行为如下:

ClientController 收到一个新的请求时,它会被处理,并且控制器会向外部设备发送一个请求并等待它的回答。
这个答案由NodeController 收到。所以当答案到来时,接收到的信息会被持久化在数据库中,并向ClientController发送信号以唤醒它。

当这个控制器被唤醒并尝试从数据库中检索更新的信息时,我的问题就出现了。该信息不是刚刚存储的信息,而是之前存储的信息。

这是ClientController的代码的sn-p,块和检索信息发生的地方:

// Retrieves the list of nodes that are going to be requested
requestedNodes = (List<Node>) nodeRepository.findAll();

System.out.println("BEFORE");
for (Node node : nodes)
    System.out.println(node.getNodeId() + ": " + node.getStatus());

// Sends a request to the nodes
// The Controller is blocked here until all answers have been received
fetchNodes(requestedNodes, DevicePing[0], null);

// Retrieves the list of nodes again
nodes = nodeRepository.findAll();

System.out.println("AFTER");
for (Node node : nodes)
    System.out.println(node.getNodeId() + ": " + node.getStatus());

这是打印出来的数据:

BEFORE:
321: dead
1: dead
4: dead

AFTER:
321: dead
4: dead
1: dead

如您所见,状态相同,但第二次应该是“活着”。

我检查了数据是否正确存储,并且是正确的。在解锁 ClientController 之前,新数据在数据库中是可用的。

我还尝试使用 JDBC 而非存储库来检索新数据。在这种情况下,新信息被正确检索。所以我认为它一定与Repository 有关,但我找不到它是什么。也许有一些缓存或刷新问题。我尝试在保存新数据后立即执行nodeRepository.flush(),然后在检索它之前执行,但没有成功。

我希望有人可以帮助我。提前致谢

【问题讨论】:

    标签: java spring jpa spring-data-jpa


    【解决方案1】:

    终于找到答案了。该问题确实与某些缓存问题有关。

    Hibernate 正在缓存使用函数 nodeRepository.findAll() 检索到的实体,因此当我调用函数 nodeRepository.findAll() 时,它会返回缓存的信息,而不是执行对数据库的查询。

    解决方案是在检索更新数据之前从EntityManager 调用函数clear()

    // Sends a request to the nodes
    // The Controller is blocked here until all answers have been received
    fetchNodes(requestedNodes, DevicePing[0], null);
    
    // Clears the cache to avoid inconsistency
    entityManager.clear();
    
    // Retrieves the list of nodes again
    nodes = nodeRepository.findAll();
    

    【讨论】:

      【解决方案2】:
      EntityManager entityManager;
      @Autowired
      public Service(final EntityManager entityManager) {
          this.entityManager = entityManager;
      }
      entityManager.clear();
      

      这对我有用,谢谢

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-22
      • 2020-10-11
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多