У меня возникла проблема, когда экземпляр Validation
добавлен в коллекцию на экземпляр Step
. декларация выглядит следующим образом:Непоследовательность кэша. Объект не всегда сохраняется в кэше. Коллекция
Шаг Класс:
@Entity
@Table
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Step extends AbstractEntity implements ValidatableStep {
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "step_id", nullable = false)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<Validation> validations = new HashSet<>();
@Override
public void addValidation(Validation validation) {
// do some stuff
...
// add validation instance to collection
getValidations().add(validation);
}
}
Validation класс:
@Entity
@Table
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Validation extends AbstractEntity {
//some properties
}
Оба класса Cacheable
с READ_WRITE
стратегии применяются. Однонаправленная коллекция Validation
с также кэшируется с той же стратегией.
Можно было бы ожидать, когда транзакция чтения и записи, которая вызывает addValidation(new Validation('userName'));
, совершит, новый Validation
будет виден в последующей транзакции только для чтения. Странно то, что иногда он работает, а иногда он не работает ...
Первая транзакция всегда преуспевает; мы видим, что новая валидация сохраняется в базе данных и свойство версии Step
(для оптимистичных блокирующих пупок) увеличивается. Но иногда, вторая транзакция чтения содержит Step
экземпляра с пустым Validation
Коллекции ...
Нашего Hibernate кэширование конфигурации выглядит следующим образом:
hibernate.cache.use_second_level_cache = true
hibernate.cache.use_query_cache = true
hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.cache.provider_configuration_file_resource_path = classpath:ehcache.xml
net.sf.ehcache.hibernate.cache_lock_timeout = 10000
Любой идея, что вызывает это странное (и случайное) поведение?
На самом деле, у меня нет таблицы ссылок. У проверки есть только внешний ключ к шагу. Таким образом, add/remove должен запускать только одну таблицу. Во всяком случае, я сделал свои отношения двунаправленными, и это сделало трюк! Однако я не понимаю, почему кеш второго уровня требует двунаправленного отношения? Мое приложение полон одно направленное (потому что bi не всегда имеет смысл). Означает ли это, что мне приходится реорганизовывать все отношения? Я использую во всех коллекциях стратегию кэширования NONSTRICT_READ_WRITE или READ_WRITE ... – user2054927
«Step» является родителем ассоциации, а «Validation» является Child. В отношениях «Родитель-ребенок» Родитель является стороной «один-ко-многим», и его лучше сопоставлять. Часто вы можете превратить это в однонаправленную связь, которая требует удаления стороны «один-ко-многим» и оставления только ассоциации «один-ко-многим». Однонаправленная связь «один-ко-многим» всегда использует таблицу ссылок, и это не очень практично. –
Thx для уточнения этого! – user2054927