如何仅在 json 有效时缓存

How to cache only when the json is valid

我有一个 spring rest api 应用程序正在使用 HATEOAS/PagingAndSortingRepository 完成大部分繁重的工作。

我已经使用番石榴实现了缓存,但是我遇到了问题,当用户在 api 调用中途取消请求时,它会缓存不完整的 json 并重新提供 60 秒.

我正在尝试使用 @Cacheable 注释的 unless="" 参数。以前,我只使用了 unless="#result == null",但不处理不完整或无效的 json。

这好像也不行。所以现在我正在尝试使用 com.google.gson.JsonParser 来解析结果并在适用时使其无效。

存储库

    @RepositoryRestResource(path = "products", collectionResourceRel = "products")
    public interface ProductEntityRepository extends PagingAndSortingRepository<ProductEntity, String> {
        JsonParser parser = new JsonParser(); 

        @Cacheable(value = CacheConfig.STORE_CACHE)
        ProductEntity findByName(String name); 
    }

缓存配置

    public final static String PRODUCTS_CACHE = "products";

    @Bean
    public Cache productsCache() {
        return new GuavaCache(PRODUCTS_CACHE, CacheBuilder.newBuilder()
                .expireAfterWrite(60, TimeUnit.SECONDS)
                .build());
    }

如何检测 unless="" 参数中的无效 json?

我找到了我自己的问题!

当我中断api对localhost/products的请求并重新请求时,终于看到了无法获取onetomany映射的错误。我认为错误是 lazy initialization error for a collection

我通过将 @LazyCollection(LazyCollectionOption.FALSE) 添加到我的模型中解决了这个问题,其中 @OneToMany@ManyToOne 映射被标定了。

例如:

    @Entity(name = "product")
    @Table(name = "products", schema = "${DB_NAME}", catalog = "")
    public class ProductEntity {
        private Integer id;
        private String name;
        private List shipments = new ArrayList<>();

        @Id
        @Column(name = "id", nullable = false)
        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        @Basic
        @Column(name = "name", nullable = false, length = 10)
        public String getName() {  return name;  } 
        public void setName(String name) {
            this.name = name;
        }

        @OneToMany(mappedBy = "shipmentID", targetEntity=ShipmentEntity.class)
        @LazyCollection(LazyCollectionOption.FALSE)
        public Collection<ShipmentEntity> getShipments() { return shipments; }
        public void setShipments(Collection<ShipmentEntity> shipments) { this.shipments = shipments; }


    }