如何仅在json有效时进行缓存

时间:2018-08-14 16:23:29

标签: spring spring-boot spring-data-jpa spring-data guava

我有一个Spring Rest API应用程序,它使用HATEOAS / PagingAndSortingRepository来完成大部分繁重的工作。

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

我正在尝试使用unless=""批注的@Cacheable参数。以前,我只是使用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?

1 个答案:

答案 0 :(得分:0)

我想出了自己的问题!

当我中断对localhost/products的api请求并重新请求时,我终于看到一个关于无法获取单原子映射的错误。我相信错误是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; }


    }