CacheLoader多次加载相同的密钥

时间:2015-06-29 20:36:23

标签: java web-services caching soap

我在cacheIterator中获得了重复的密钥。

我正在使用SOAP调用Web服务来为保险公司评估策略。我试图使用Cachebuilder / loader将DTO作为密钥存储,并将服务的响应存储为值。根据我的研究,.get和.getUnchecked方法将从缓存中获取一个值,如果不存在,它会将该值加载到缓存中。 这是一些代码:

public class CacheLoaderImpl
{
   private static CacheLoaderImpl instance = null;
   private static LoadingCache<PolicyDTO, RatingServiceObjectsResponse> responses;

   protected CacheLoaderImpl()
   {
      responses = CacheBuilder.newBuilder()
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build(
                new CacheLoader<PolicyDTO, RatingServiceObjectsResponse>() {
                  public RatingServiceObjectsResponse load(PolicyDTO key)
                        throws Exception
                  {
                      return getResponse(key);
                  }
                });
   }

   public static CacheLoaderImpl getIntance()
   {
      if(instance == null)
      {
         instance = new CacheLoaderImpl();
      }

      return instance;
   }

   public LoadingCache<PolicyDTO, RatingServiceObjectsResponse> getResponses()
   {
      return responses;
   }

   public RatingServiceObjectsResponse getResponse(PolicyDTO key) throws ExecutionException
   {
     RatingServiceObjectsResponse response = new RatingServiceObjectsResponse();
     try
     {
         response = new CGIRatabaseServiceImpl().getCoverages(key);
     }
     catch (RemoteException e)
     {
        e.printStackTrace();
     }
     catch (IllegalArgumentException e)
     {
        e.printStackTrace();
     }
     return response;

   }

}

这就是我调用get方法的地方:

RatingServiceObjectsResponse response = CacheLoaderImpl.getIntance().getResponses().get(policy.toCoveragesCallDTO()); 

我假设可能是比较不同的内存地址所以我覆盖了toString方法将DTO对象转换为JSON。在检查缓存时,我可以看到密钥与比较工具完全相同。然而,它们仍然存储并且每次都在调用服务。我尝试覆盖PolicyDTO上的equals方法,但是在我调试时它永远不会被击中。

如何让缓存加载器仅加载不同键的值并将现有值拉出原来的值?

我想我不知道cacheLoader实际上是如何工作的。我感谢任何帮助或建议。

PolicyDTO课程:

public class PolicyDTO extends AbstractDto implements IPolicyDTO
{
   private ArrayList<ILineOfBusinessDTO> lobDTOs = new ArrayList<ILineOfBusinessDTO>();
   private String pcInd;
   private String ratingEffectiveDate;
   private String companyName;

   public String getPcInd()
   {
      return pcInd;
   }

   public void setPcInd(String pcInd)
   {
      this.pcInd = pcInd;
   }

   public String getRatingEffectiveDate()
   {
      return ratingEffectiveDate;
   }

   public void setRatingEffectiveDate(AdvancedDate ratingEffectiveDate)
   {
      if(ratingEffectiveDate != null)
      {
         this.ratingEffectiveDate = ratingEffectiveDate.toFormattedStringMMDDYYYY();
      }
      else
      {
         this.ratingEffectiveDate = new AdvancedDate().toFormattedStringMMDDYYYY();
      }
   }

   public String getCompanyName()
   {
      return companyName;
   }

   public void setCompanyName(String companyName)
   {
      this.companyName = companyName;
   }

  public DtoType getType()
   {
       return hasGetCoveragesCoverageDTO() ? DtoType.GET_COVERAGE_POLICY : DtoType.RATE_POLICY;
   }

   public boolean hasGetCoveragesCoverageDTO()
   {
       if(lobDTOs != null)
       {
           for(ILineOfBusinessDTO lineDTO : lobDTOs)
           {
               if(lineDTO.hasGetCoveragesCoverageDTO())
               {
                   return true;
               }
           }
       }

       return false;
   }

    @Override
    public void addLob(ILineOfBusinessDTO lob) {

        lobDTOs.add(lob);
    }

    @Override
    public Iterator<ILineOfBusinessDTO> getLobIterator() {

        return lobDTOs.iterator();
    }

    public ICoverageDTO findCoverage(String coverageID)
    {
        ICoverageDTO coverageDTO = null;

        for(ILineOfBusinessDTO lineDTO : lobDTOs)
        {
            coverageDTO = lineDTO.findCoverage(coverageID);

            if(coverageDTO != null)
            {
                return coverageDTO;
            }
        }

        return null;
    }
    @Override
    public String toString()
    {
       return JSONConversionUtility.convertPolicyDTO(this);
    }

    @Override
   public int hashCode()
   {
      final int prime = 31;
      int result = 1;
      result = prime * result
            + ((companyName == null) ? 0 : companyName.hashCode());
      result = prime * result + ((lobDTOs == null) ? 0 : lobDTOs.hashCode());
      result = prime * result + ((pcInd == null) ? 0 : pcInd.hashCode());
      result = prime
            * result
            + ((ratingEffectiveDate == null) ? 0 : ratingEffectiveDate
                  .hashCode());
      return result;
   }

    @Override 
   public boolean equals(Object object)
   {
      if(object instanceof PolicyDTO)
      {
         return object.toString().equals(this.toString());
      }
      return false;

   }
}

1 个答案:

答案 0 :(得分:3)

您的PolicyDTO班级hashCodeequals不一致 - 它违反了以下规则:

  

如果根据equals(Object)方法两个对象相等,那么   在两个对象中的每一个上调用hashCode方法必须生成   相同的整数结果。

缓存使用hashCode(非常类似于HashMap类),因此当它看到两个具有不同哈希码的密钥时,它假定它们不相等。