[英]Cache inconsistency - Entity not always persisted in cached Collection
I'm having an issue where a Validation
instance is added to a Collection on a Step
instance. 我遇到一个问题,即在Step
实例上将Validation
实例添加到Collection。 Declaration is as follows: 声明如下:
Step class: 步骤类:
@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 class: 验证类:
@Entity
@Table
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Validation extends AbstractEntity {
//some properties
}
Both classes are Cacheable
with a READ_WRITE
strategy applied. 这两个类都是Cacheable
,并且应用了READ_WRITE
策略。 The unidirectional Collection of Validation
s are also cached with same strategy. 单向的Validation
集合也使用相同的策略进行缓存。
One would expect when a read-write transaction that invokes addValidation(new Validation('userName'));
当读取事务调用addValidation(new Validation('userName'));
时,人们会期待addValidation(new Validation('userName'));
commits, the new Validation
would be visible in a subsequent read-only transaction. 提交时,新的Validation
将在后续的只读事务中可见。 The weird thing is that sometimes it does work and sometimes it doesn't work... 奇怪的是,有时它确实有效,有时它不起作用......
The first transaction always succeeds; 第一笔交易总是成功; we see the new validation being persisted in database and Step
's version property (for optimistic locking puposes) getting incremented. 我们看到新的验证在数据库中持久存在,而Step
的版本属性(用于乐观锁定目的)会增加。 But sometimes, the 2nd read transaction contains a Step
instance with an empty Validation
Collection... 但有时,第二个读取事务包含一个带有空Validation
Collection的Step
实例...
Our Hibernate caching config is as follows: 我们的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
Any idea what's causing this weird (and random) behavior? 知道造成这种奇怪(和随机)行为的原因是什么?
The Hibernate Collection Cache always invalidates existing entries and both the Entity and the Collection caches are sharing the same AbstractReadWriteEhcacheAccessStrategy , so a soft-lock is acquired when updating data. Hibernate Collection Cache总是使现有条目无效,Entity和Collection缓存共享相同的AbstractReadWriteEhcacheAccessStrategy ,因此在更新数据时会获得软锁 。
Because you are using a unidirectional one-to-many association, you will end up with a Validation
table and a Step_validation link table too. 因为您使用的是单向一对多关联,所以最终会得到Validation
表和Step_validation链接表。 Whenever you add/remove a Validation you have to hit two tables and that's less efficient. 无论何时添加/删除验证,您都必须点击两个表并且效率较低。
I suggest you adding the @ManyToOne
side in the Validation
entity and turn the @OneToMany
side into a mapped-by collection: 我建议您在Validation
实体中添加@ManyToOne
端,并将@OneToMany
端转换为映射集合:
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "step")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<Validation> validations = new HashSet<>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.