Spring / Eclipselink / MySQL проблема с данными приложения - PullRequest
0 голосов
/ 27 декабря 2011

У меня возникла странная проблема с моим приложением. Я реализовал функцию оценки купонов. В соответствии с приложением, я должен найти купон и щелкнуть по нему, чтобы отобразить страницу описания, и там есть опция рейтинга, которая используется для предпочтительного рейтинга пользователя. Что я тестирую, так это следующий сценарий: я ищу купон «Тест», нажимаю на него и захожу на страницу описания, оцениваю его и проверяю, отражен ли он в БД. Последнее оцененное значение и общая оценка будут отражены на странице описания. Затем я снова возвращаюсь на главную страницу, ищу тот же купон, нажимаю на него, чтобы перейти на страницу описания и снова оценивать. Происходит следующее: БД корректно обновляется 4-6 раз, после чего, когда я ищу этот купон и перехожу на страницу описания, он показывает предыдущее значение для рейтинга и общего рейтинга, которое может быть значением, когда его оценивали несколько раз. назад (это значение было переопределено в дБ). И затем, если я оцениваю сверху, значения не обновляются в БД. И с тех пор эта функциональность нарушается. Я попробовал несколько вариантов, отключил кеш, установил некоторые хиты на eclipselink и т. Д., Но ничего не решило проблему. Пожалуйста, поделитесь своими предложениями. Некоторые важные части из моего кода:

persistence.xml:

<shared-cache-mode>NONE</shared-cache-mode>
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.query-results-cache" value="false"/>  

Coupon и CouponRating имеют однонаправленное сопоставление «один к одному»: (Ранее я использовал двунаправленное сопоставление, тогда также была та же проблема.)

В CouponRating.java:

@Cacheable(false)
@Entity
@Table(name = "Coupon_Rating")
public class CouponsRatings {
....
....
....
@OneToOne
@JoinColumn(name="coupon_id", unique=true, nullable=false, updatable=false)
private Coupon coupon;

@Version
@Column(name="version")
private long version;

@Column(name="uuid") 
private String uuid;
....
....
....

@Override
public int hashCode() {
    int hash = 3;
    hash = 89 * hash + (this.uuid != null ? this.uuid.hashCode() : 0);
    hash = 89 * hash + Long.valueOf(this.version).intValue();
    return hash;
}

    @Override
public boolean equals(Object obj) {
  if((obj == null) || (this.getClass() != obj.getClass()))
        return false;

  CouponsRatings couponsRatings = (CouponsRatings)obj;
  return (this.version == couponsRatings.getVersion() &&
    this.uuid.equalsIgnoreCase(couponsRatings.getUuid()));
}
....
....

RatingManagerImpl.java

....
....

@Transactional
public CouponsRatings saveRating(CouponsRatings rating) throws AppException{
    return ratingDAO.saveRating(rating);
}

@Transactional
public CouponsRatings updateRating(CouponsRatings rating)
        throws AppException {
    return ratingDAO.updateRating(rating);
}

public CouponsRatings findRatingById(Long id) {
    return ratingDAO.findRatingById(id);
}

public CouponsRatings refreshObject(CouponsRatings rating) {
    return ratingDAO.refreshObject(rating);
}

....
....

В Рейтинге Дао:

....
....
private EntityManager entityManager;

@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}

@Override
public CouponsRatings saveRating(CouponsRatings rating) throws AppException {
try {
       entityManager.persist(rating);
} catch (Exception e) {
   logger.debug("Error in saving coupon. Reason: " + e.getMessage());
   throw new CouponzleAppException(e.getMessage());
}
return rating;
}

@Override
public CouponsRatings findRatingByCouponId(Long id) {
  CouponsRatings couponsRatings = null;
  try {
    couponsRatings = (CouponsRatings) entityManager
            .createNamedQuery("findRatingByCouponId")
            .setHint(QueryHints.CACHE_USAGE, 
                             CacheUsage.DoNotCheckCache)
            .setParameter(1, id).getSingleResult();
       } catch (NoResultException exception) {
        logger.error("No active couponsRatings available for coupon id : "
                    + id);
       }
    return couponsRatings;
}

@Override
public CouponsRatings updateRating(CouponsRatings rating)
        throws AppException {
    CouponsRatings updatedRating = null;
    try {
        updatedRating = entityManager.merge(rating);
    } catch (Exception e) {
        logger.debug("Error in updating coupon. Reason: " + .getMessage());
        throw new AppException(e.getMessage());
    }
    return updatedRating;
}

@Override
public CouponsRatings refreshObject(CouponsRatings rating) {
    CouponsRatings updatedRating = null;
    updatedRating = entityManager.merge(rating);
    entityManager.refresh(updatedRating);
    return rating;
    }

Из класса Action: (Только получение и обновление senario)

// this sometimes loads old date as i have described
couponsRating = ratingsManager.findRatingByCouponId(Long.valueOf(
                couponId).longValue());

cupnsRating.setCurrentRating(currentRating);
cupnsRating.setLastRatingDate(new Date());
cupnsRating.setRatingSum(ratingSum);
cupnsRating.setTotalRatings(totalRatings);
couponsRating = ratingsManager.updateRating(cupnsRating);
// I tried to refresh updated object after i get the issue, but still no luck:
// couponsRating = ratingsManager.refreshObject(couponsRating);

Пожалуйста, дайте мне знать, если я делаю что-то не так. Благодаря.

1 Ответ

0 голосов
/ 03 января 2012

Проверьте, как рейтингиManager хранятся и используются повторно. Я предполагаю, что существует несколько экземпляров, и каждый хранит свой собственный экземпляр EntityManager. EntityManager имеет кэш, похожий на транзакцию, поэтому он не увидит изменений, внесенных в область действия других EntityManager, если только его копия сущности не будет обновлена.

Если это так, вы можете попробовать вызвать refresh (после исправления вашего метода refreshObject, чтобы он возвращал обновленный объект, а затем повторно применить изменения), или исключить / очистить объект из EntityManager в соответствующее время, чтобы объекты были перезагружены из база данных.

...