Я получаю дубликаты ключей в своем кэше.CacheLoader загружает одни и те же ключи в несколько раз
Я звоню в веб-службу, используя SOAP для оценки политик для страховой компании. Я пытаюсь использовать 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;
}
}
И это где я называю метод прибудет:
RatingServiceObjectsResponse response = CacheLoaderImpl.getIntance().getResponses().get(policy.toCoveragesCallDTO());
Я был в предположении, что, возможно, сравнивали адреса памяти, которые будут отличаться, так что я переписал toString для преобразования объекта DTO в JSON. После проверки кеша я вижу, что ключи точно совпадают с инструментом сравнения. Тем не менее, они все еще хранятся и каждый раз звонят в службу. Я попытался переписать метод equals в PolicyDTO, но он никогда не попадает, когда я отлаживаю.
Как я могу заставить кеш-загрузчик загружать только значения разных ключей и вытаскивать существующие значения изначально?
Я думаю, что у меня просто нет четкой идеи о том, как работает 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. Как и где вы помещаете вещи в cacheLoader и 2. PolicyDTO class –
Вы переопределили методы 'equals' ** и **' hashCode'? –
Ben Manes - Да, но после отладки я обнаружил, что он никогда не попадает ни в один из методов, только мой toString переопределяет. – unsensibled