Ich habe ein Problem, bei dem eine Validation
Instanz zu einer Collection in einer Step
Instanz hinzugefügt wird. Erklärung ist wie folgt:Cache-Inkonsistenz - Entität nicht immer im Cache gespeichert Auflistung
Schritt Klasse:
@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 Klasse:
@Entity
@Table
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Validation extends AbstractEntity {
//some properties
}
Beide Klassen sind Cacheable
mit einer READ_WRITE
angewendet Strategie. Die unidirektionale Sammlung von Validation
s wird ebenfalls mit derselben Strategie zwischengespeichert.
Man würde erwarten, wenn eine Lese-Schreib-Transaktion, die addValidation(new Validation('userName'));
commits aufruft, die neue Validation
in einer nachfolgenden schreibgeschützten Transaktion sichtbar wäre. Das Seltsame ist, dass es manchmal funktioniert und manchmal nicht funktioniert ...
Die erste Transaktion ist immer erfolgreich; Wir sehen, dass die neue Validierung in der Datenbank beibehalten wird und die Versionseigenschaft Step
(für optimistisches Sperren) erhöht wird. Aber manchmal, enthält die zweite Lesetransaktion eine Step
Instanz mit einem leeren Validation
Sammlung ...
Unsere Hibernate Caching Config ist wie folgt:
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
Jede Idee, was dieses seltsame verursacht (und zufällig) Verhalten?
Eigentlich habe ich keinen Link-Tabelle haben. Die Validierung hat nur einen Fremdschlüssel für Step. Ein add/remove sollte also nur eine Tabelle auslösen. Wie auch immer, ich habe meine Beziehung bidirektional gemacht und das hat den Trick gemacht! Allerdings verstehe ich nicht, warum der 2nd Level Cache eine bidirektionale Beziehung benötigt? Meine Anwendung ist voll von direktionalen (weil Bi nicht immer sinnvoll ist). Bedeutet das, dass ich alle Beziehungen umgestalten muss? Ich benutze bei allen Sammlungen eine Caching-Strategie NONSTRICT_READ_WRITE oder READ_WRITE ... – user2054927
Der 'Schritt' ist das Elternteil der Assoziation und die' Validierung' ist das Kind. In einer Parent-Child-Beziehung ist Parent die Eins-zu-Viele-Seite und es ist besser, sie ebenfalls zu kartieren. Häufig können Sie dies in eine unidirektionale Verknüpfung umwandeln, die es erfordert, die Eins-zu-viele-Seite zu entfernen und nur die Viele-zu-Eins-Verknüpfung zu belassen. Eine unidirektionale Eins-zu-Viele-Verknüpfung verwendet immer eine Verknüpfungstabelle, und das ist nicht sehr praktisch. –
Thx für die Klärung! – user2054927