【问题标题】:How to cache only when the json is valid仅当json有效时如何缓存
【发布时间】:2018-08-14 16:23:28
【问题描述】:

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

我已经使用 guava 实现了缓存,但是我遇到了问题,当用户在 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?

【问题讨论】:

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


    【解决方案1】:

    我自己解决了问题!

    当我中断对localhost/products的api请求并重新请求时,我终于看到了一个关于无法获取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; }
    
    
        }
    

    【讨论】:

      猜你喜欢
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      相关资源
      最近更新 更多