Spring JpaRepository未返回更新的数据

时间:2014-04-28 10:56:41

标签: java spring spring-data-jpa

我正在开发一个基于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收到新请求时,会对其进行处理,并且Controller会向外部设备发送请求并等待其回答。
这个答案由NodeController收到。因此,当答案到达时,收到的信息将保留在数据库中,并将信号发送到ClientController以将其唤醒。

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

以下是阻止和检索信息发生的ClientController代码片段:

// 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的intead来检索新数据。在这种情况下,正确检索新信息。所以我认为它必须与Repository有关,但我无法找到它。也许有一些缓存或刷新问题。我尝试在保存新数据后立即执行nodeRepository.flush(),并在检索之前立即执行{{1}},但它没有用。

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

2 个答案:

答案 0 :(得分:4)

最后我能找到答案。问题确实与一些缓存问题有关。

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

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

// 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();

答案 1 :(得分:-1)

EntityManager entityManager;
@Autowired
public Service(final EntityManager entityManager) {
    this.entityManager = entityManager;
}
entityManager.clear();

这对我有用,谢谢