我有一个简单的应用程序,可以定期从Postgres视图中读取数据。为此,我设置了一个Sping Boot (v3)应用程序,如下所示:
订单实体:
@Entity
@Table(name = "order_view") //order_view is a view
@Getter
@Setter
@ToString
public class Order implements Serializable {
@Id
@Column(name = "ID", columnDefinition = "numeric")
private Long id;
@Column(name = "CLIENT_NAME")
private String clientName;
}
字符串
订单回购:
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
}
型
订单服务:
@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
private final OrderRepository orderRepository;
@Override
@Transactional(readOnly = true)
public List<Order> getAllOrders() {
return orderRepository.findAll();
}
}
型
**
@Service
@RequiredArgsConstructor
public class SchedulerService {
private final OrderService orderService;
@Scheduled(fixedDelay = 5000)
public void readFromDB() {
List<Order> orders= orderService.getAllOrders();
log.debug("DATA: {}", orders);
}
型
一切正常,但问题是,当视图数据更新时(例如通过另一个应用程序),readFromDB()
的输出仍然给我旧数据,而查询视图直接给我最新数据。
甚至我创建了一个rest控制器,如下所示,直接调用OrderService,令人惊讶的是,该控制器还返回一个陈旧的数据,而不是新的:
@GetMapping(path = "/orders")
public List<Order> getAllData() {
return orderService.getAllOrders();
}
型
我只有在重新启动应用程序后才能获得新数据,而且,当视图更新时,输出不会反映在视图输出中。
现在,当我删除@Scheduled
注解(禁用调度程序)时,控制器按预期工作并返回最新数据!
我尝试了很多建议,比如在@Scheduled
方法中调用entiyManager.clear()
,但都没有成功。此外,我添加了不同传播和隔离类型的@Transactional()
,也没有成功。
**
我已经重新测试了这个问题,将不同的实体Map到常规表而不是Map到视图,这个问题不再发生。
另外,我通过@Scheduled
方法直接通过JdbcTemplate
查询视图,现在我得到了更新的数据。
1条答案
按热度按时间uyto3xhc1#
我认为,你在这种情况下滥用了Hibernate,因为Hibernate并不期望其他任何东西来改变数据。Hibernate主要不是用来读取正在被其他东西更新的数据。至少这是我个人的观点。
如果你有一个小的应用程序,它只对数据库做那么一点事情,我建议你不要使用Hibernate。
但我认为你的问题在于Hibernate缓存:
detach()
和clear()
方法从Hibernate L1缓存中清除会话缓存我希望你能解决这个恼人的问题!