import java.util.Arrays;
import java.util.List;
-import org.apache.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.vaadin.viritin.fields.LazyComboBox.FilterableCountProvider;
import org.vaadin.viritin.fields.LazyComboBox.FilterablePagingProvider;
/**
* @author a.kohlbecker
* @since Jun 7, 2017
- *
*/
-public class CdmFilterablePagingProvider<T extends IdentifiableEntity, V extends T> implements FilterablePagingProvider<V>, FilterableCountProvider {
+public class CdmFilterablePagingProvider<T extends IdentifiableEntity, V extends T>
+ implements FilterablePagingProvider<V>, FilterableCountProvider {
+ private static final Logger logger = LogManager.getLogger();
private static final List<String> DEFAULT_INIT_STRATEGY = Arrays.asList("$");
- private static final Logger logger = Logger.getLogger(CdmFilterablePagingProvider.class);
+ public static final String QUERY_STRING_PLACEHOLDER = "{query-string}";
private int pageSize = 20;
private List<OrderHint> orderHints = OrderHint.ORDER_BY_TITLE_CACHE.asList();
- List<String> initStrategy = DEFAULT_INIT_STRATEGY;
+ private List<String> initStrategy = DEFAULT_INIT_STRATEGY;
private List<Criterion> criteria = new ArrayList<>();
private List<Restriction<?>> restrictions = new ArrayList<>();
-
- /**
- * @return the matchMode
- */
protected MatchMode getMatchMode() {
return matchMode;
}
-
- /**
- * @param matchMode the matchMode to set
- */
protected void setMatchMode(MatchMode matchMode) {
this.matchMode = matchMode;
}
- /**
- * @return the orderHints
- */
protected List<OrderHint> getOrderHints() {
return orderHints;
}
-
- /**
- * @param orderHints the orderHints to set
- */
protected void setOrderHints(List<OrderHint> orderHints) {
this.orderHints = orderHints;
}
/**
* With defaults for matchMode = MatchMode.ANYWHERE and orderHints = OrderHint.ORDER_BY_TITLE_CACHE
- *
*/
public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service) {
this(service, null);
/**
* With defaults for matchMode = MatchMode.ANYWHERE and orderHints = OrderHint.ORDER_BY_TITLE_CACHE
- *
*/
public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, Class<V> type) {
super();
this.type = type;
this.service = service;
- // Logger.getLogger("org.hibernate.SQL").setLevel(Level.TRACE);
+ // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
}
-
public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, MatchMode matchMode, List<OrderHint> orderHints) {
this(service, null, matchMode, orderHints);
}
public <S extends T> CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, Class<V> type, MatchMode matchMode, List<OrderHint> orderHints) {
- super();
this.type = type;
this.service = service;
this.matchMode = matchMode;
this.orderHints = orderHints;
- // Logger.getLogger("org.hibernate.SQL").setLevel(Level.TRACE);
+ // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
}
- /**
- * {@inheritDoc}
- */
@Override
public List<V> findEntities(int firstRow, String filter) {
+ checkNotMixed();
+
Integer pageIndex = firstRow / pageSize;
Pager<V> page;
- if(!restrictions.isEmpty() && criteria.isEmpty()){
- page = (Pager<V>) service.findByTitleWithRestrictions(
+ clearSession(); // clear the session from remains of previous service calls, see issue #7559
+ if(!restrictions.isEmpty()){
+ List<Restriction<?>> preparedRestrictions = prepareRestrictions(filter, matchMode);
+ page = service.findByTitleWithRestrictions(
type,
filter,
matchMode,
- restrictions,
+ preparedRestrictions,
pageSize,
pageIndex ,
orderHints,
initStrategy
);
- } else if(restrictions.isEmpty() && !criteria.isEmpty()){
- page = (Pager<V>) service.findByTitle(
+ } else {
+ page = service.findByTitle(
type,
filter,
matchMode,
orderHints,
initStrategy
);
- } else {
- // this will never be reaced sind the size() method is always called before.
- throw new RuntimeException("Citeria and Restrictions must not be used at the same time");
}
+
if(logger.isTraceEnabled()){
logger.trace("findEntities() - page: " + page.getCurrentIndex() + "/" + page.getPagesAvailable() + " totalRecords: " + page.getCount() + "\n" + page.getRecords());
}
+
+ // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
return page.getRecords();
}
- /**
- * {@inheritDoc}
- */
@Override
public int size(String filter) {
- Pager<V> page;
- if(!restrictions.isEmpty() && criteria.isEmpty()){
- page = (Pager<V>) service.findByTitleWithRestrictions(
- type,
- filter,
- matchMode,
- restrictions,
- 1,
- 0,
- null,
- null
- );
- } else if(restrictions.isEmpty() && !criteria.isEmpty()){
- page = (Pager<V>) service.findByTitle(
- type,
- filter,
- matchMode,
- criteria,
- 1,
- 0,
- null,
- null
- );
+ checkNotMixed();
+
+ clearSession(); // clear the session from remains of previous service calls, see issue #7559
+ long count = 0;
+ if(!restrictions.isEmpty()){
+ // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
+ List<Restriction<?>> preparedRestrictions = prepareRestrictions(filter, matchMode);
+ count = service.countByTitleWithRestrictions(type, filter, matchMode, preparedRestrictions);
} else {
- throw new RuntimeException("Citeria and Restrictions must not be used at the same time");
+ count = service.countByTitle(type, filter, matchMode, criteria);
}
+
if(logger.isTraceEnabled()){
- logger.trace("size() - count: " + page.getCount().intValue());
+ logger.trace("size() - count: " + count);
}
- return page.getCount().intValue();
+ return Long.valueOf(count).intValue();
}
/**
- * @return the pageSize
+ * see issue #7559
*/
+ public void clearSession() {
+ Session session = service.getSession();
+ if(session.isOpen()){
+ session.clear();
+ }
+ }
+
+ private List<Restriction<?>> prepareRestrictions(String filter, MatchMode matchMode) {
+ List<Restriction<?>> prepared = new ArrayList<>(restrictions.size());
+ for(Restriction<?> r : restrictions) {
+ List<Object> values = new ArrayList<>(r.getValues().size());
+ for(Object v : r.getValues()){
+ if(v instanceof String){
+ String expandedValue = ((String)v).replace(QUERY_STRING_PLACEHOLDER, matchMode.queryStringFrom(filter));
+ values.add(expandedValue);
+ } else {
+ values.add(v);
+ }
+ }
+ prepared.add(new Restriction<>(r.getPropertyName(), r.getOperator(), r.getMatchMode(), values.toArray(new Object[values.size()])));
+ }
+ return prepared;
+ }
+
+ protected void checkNotMixed() {
+ if(!restrictions.isEmpty() && !criteria.isEmpty()){
+ throw new RuntimeException("Citeria and Restrictions must not be used at the same time");
+ }
+ }
+
public int getPageSize() {
return pageSize;
}
- /**
- * @param pageSize the pageSize to set
- */
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
- /**
- * @return the initStrategy
- */
public List<String> getInitStrategy() {
return initStrategy;
}
- /**
- * @param initStrategy the initStrategy to set
- */
public void setInitStrategy(List<String> initStrategy) {
this.initStrategy = initStrategy;
}
/**
* The list of restrictions is initially empty.
+ * <p>
+ * Occurrences of the {@link QUERY_STRING_PLACEHOLDER} in the value
+ * of String type Restrictions will be replaced by the <code>filter</code> parameter passed to the paging provider.
+ *
*
* @return the restrictions
*/
return restrictions;
}
+ /**
+ * Occurrences of the {@link QUERY_STRING_PLACEHOLDER} in the value
+ * of String type Restrictions will be replaced by the <code>filter</code> parameter passed to the paging provider.
+ *
+ * @param restriction
+ */
public void addRestriction(Restriction<?> restriction){
restrictions.add(restriction);
}
-}
+}
\ No newline at end of file