Commit 991b1177 authored by Thomas Huster's avatar Thomas Huster

[21097] update model query executeAsStream without caching, add get size

parent 9d613275
Pipeline #16334 passed with stages
in 4 minutes and 48 seconds
package ch.elexis.core.jpa.entities;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
......@@ -69,11 +68,11 @@ public class Behandlung extends AbstractEntityWithId implements EntityWithId, En
@OneToMany(fetch = FetchType.LAZY)
@JoinTable(name = "behdl_dg_joint", joinColumns = @JoinColumn(name = "BehandlungsID"), inverseJoinColumns = @JoinColumn(name = "DiagnoseID"))
private List<Diagnosis> diagnoses = new ArrayList<>();
private List<Diagnosis> diagnoses;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "behandlung")
private List<Verrechnet> billed = new ArrayList<>();
private List<Verrechnet> billed;
@Mutable
@Convert(converter = VersionedResourceConverter.class)
......
......@@ -282,16 +282,46 @@ public abstract class AbstractModelQuery<T> implements IQuery<T> {
return query;
}
private TypedQuery<Long> getSizeQuery(){
CriteriaQuery<Long> criteriaQuery = criteriaBuilder.createQuery(Long.class);
criteriaQuery = criteriaQuery.select(criteriaBuilder.count(rootQuery));
// apply the predicate groups to the criteriaQuery
int groups = predicateGroups.getPredicateGroupsSize();
if (groups > 0) {
if (groups == 2
&& (EntityWithDeleted.class.isAssignableFrom(entityClazz) && !includeDeleted)) {
andJoinGroups();
groups = predicateGroups.getPredicateGroupsSize();
}
if (groups == 1) {
criteriaQuery =
criteriaQuery.where(predicateGroups.getCurrentPredicateGroup().getPredicate());
} else {
throw new IllegalStateException("Query has open groups [" + groups + "]");
}
}
TypedQuery<Long> query = entityManager.createQuery(criteriaQuery);
return query;
}
@SuppressWarnings("unchecked")
@Override
public Stream<T> executeAsStream(){
Stream<T> ret = getTypedQuery().getResultStream().map(
TypedQuery<?> query = getTypedQuery();
query.setHint(QueryHints.MAINTAIN_CACHE, HintValues.FALSE);
Stream<T> ret = query.getResultStream().map(
e -> (T) adapterFactory.getModelAdapter((EntityWithId) e, clazz, true).orElse(null));
// detach and clear L1 cache
entityManager.clear();
return ret;
}
@Override
public long getSize(){
return getSizeQuery().getSingleResult();
}
@SuppressWarnings("unchecked")
@Override
public List<T> execute(){
......
......@@ -31,6 +31,8 @@ public class EntityChangeEventListener implements EventHandler {
new WeakHashMap<EntityWithId, List<WeakReference<AbstractIdModelAdapter<?>>>>();
}
private int addCount;
public void add(AbstractIdModelAdapter<?> adapter){
synchronized (listenerMap) {
EntityWithId entity = adapter.getEntity();
......@@ -38,6 +40,34 @@ public class EntityChangeEventListener implements EventHandler {
listeners.add(new WeakReference<AbstractIdModelAdapter<?>>(adapter));
listenerMap.put(entity, listeners);
if (addCount++ > 10000) {
if(listenerMap.size() > 10000) {
cleanup();
}
addCount = 0;
}
}
}
private void cleanup(){
Iterator<EntityWithId> entitiesIter = listenerMap.keySet().iterator();
while (entitiesIter.hasNext()) {
EntityWithId entity = entitiesIter.next();
List<WeakReference<AbstractIdModelAdapter<?>>> listeners = listenerMap.get(entity);
Iterator<WeakReference<AbstractIdModelAdapter<?>>> iter = listeners.iterator();
while (iter.hasNext()) {
WeakReference<AbstractIdModelAdapter<?>> reference = iter.next();
if (reference != null) {
AbstractIdModelAdapter<?> adapter = reference.get();
if (adapter == null) {
iter.remove();
}
}
}
if (listeners.isEmpty()) {
entitiesIter.remove();
}
}
}
......
......@@ -119,13 +119,13 @@ public interface IQuery<T> {
*/
public Stream<T> executeAsStream();
// /**
// * Set a limit on the number of results to be returned. This is equivalent to
// * the SQL limit command.
// *
// * @param limit non negative value
// */
// public void setLimit(int limit);
/**
* Execute a count of the expected results of the query. Use to determine expected size of
* {@link #executeAsStream()}.
*
* @return
*/
public long getSize();
/**
* Execute the query and return a single result. If more than one result
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment