CacheLoader loads the same keys multiple times

I am getting duplicate keys in my cacheIterator.

I am calling a web service using SOAP to evaluate policies for an insurance company. I am trying to use Cachebuilder / loader to store DTO as key and response from service as value. From what I've researched, the .get and .getUnchecked methods will get the value from the cache, and if it doesn't, it will load that value into the cache. here is the code:

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;

   }

}

      

And here I am calling the get method:

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

      

I was under the assumption that perhaps it was comparing memory addresses that would be different, so I rewrote the toString method to convert the DTO object to JSON. After checking the cache, I see that the keys match exactly with the compare tool. However, they are still stored and call the service every time. I tried to overwrite the equals method in PolicyDTO, but it never hits when debugging.

How can I force the cache loader to only load the values โ€‹โ€‹of different keys and pull the existing values โ€‹โ€‹out initially?

I think I just don't have a clear idea of โ€‹โ€‹how the cacheLoader works. I appreciate any help or suggestions.

PolicyDTO class:

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;

   }
}

      

+3


source to share


1 answer


PolicyDTO

hashCode

Doesn't match in your class equals

- it breaks the following rule:

If two objects are equal according to the method equals(Object)

, then calling the method hashCode

on each of the two objects should have the same integer result.



The cache uses hashCode

(as a class HashMap

), so when it sees two keys with different hash codes, it assumes they are not equal.

+3


source







All Articles