InventoryRepositoryCustomImpl.java
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.persistence;
import java.util.concurrent.TimeUnit;
import javax.persistence.EntityManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.gringlobal.model.Accession;
import org.gringlobal.model.Inventory;
import org.gringlobal.model.QAccession;
import org.gringlobal.model.QInventory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import com.blazebit.persistence.CriteriaBuilderFactory;
import com.blazebit.persistence.querydsl.BlazeJPAQuery;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class InventoryRepositoryCustomImpl implements InventoryRepositoryCustom {
@Autowired
private CriteriaBuilderFactory criteriaBuilderFactory;
@Autowired
private EntityManager entityManager;
@Autowired
private JPAQueryFactory jpaQueryFactory;
/**
* Find max number part 2.
*
* @param accession the accession
* @param inventoryNumberPart1 the inventory number part 1
* @param inventoryNumberPart3 the inventory number part 3
* @param formType the form type
* @return the long
*/
@Override
public long findMaxNumberPart2(final Accession accession, final String inventoryNumberPart1, String inventoryNumberPart3, String formType) {
// BooleanExpression predicate =
// QInventory.inventory.accession.eq(accession).and(QInventory.inventory.inventoryNumberPart1.eq(numberPart1));
// We are ignoring accession
BooleanExpression predicate;
if (inventoryNumberPart1 != null) {
predicate = QInventory.inventory.inventoryNumberPart1.eq(inventoryNumberPart1);
} else {
predicate = QInventory.inventory.inventoryNumberPart1.isNull();
}
if (StringUtils.isNotBlank(inventoryNumberPart3)) {
predicate = predicate.and(QInventory.inventory.inventoryNumberPart3.eq(inventoryNumberPart3));
} else {
predicate = predicate.and(QInventory.inventory.inventoryNumberPart3.isNull());
}
if (formType != null) {
predicate = predicate.and(QInventory.inventory.formTypeCode.eq(formType));
} else {
predicate = predicate.and(QInventory.inventory.formTypeCode.isNull());
}
final JPAQuery<Long> x = jpaQueryFactory.from(QInventory.inventory).select(QInventory.inventory.inventoryNumberPart2.max()).where(predicate);
Long max = x.fetchFirst();
return max == null || max < 0 ? 0 : max.longValue();
}
@Override
public Inventory getSystemInventory(Accession accession) {
return jpaQueryFactory.selectFrom(QInventory.inventory)
// accession
.where(QInventory.inventory.accession().eq(accession)
// FTC == **
.and(QInventory.inventory.formTypeCode.eq(Inventory.SYSTEM_INVENTORY_FTC)))
// One
.fetchOne();
}
@Override
public void setInventoryNumber(Long inventoryId, String inventoryNumber) {
jpaQueryFactory.update(QInventory.inventory)
.where(QInventory.inventory.id.eq(inventoryId))
.set(QInventory.inventory.inventoryNumber, inventoryNumber)
.execute();
}
@Override
public Page<AggregatedInventoryQuantity> aggregateQuantity(Predicate filters, Pageable page) {
assert filters != null;
var groupByProperties = new com.querydsl.core.types.Path[] {
QInventory.inventory.accession().id,
QInventory.inventory.formTypeCode,
QInventory.inventory.availabilityStatusCode,
QInventory.inventory.quantityOnHandUnitCode
};
var aggQuery = new BlazeJPAQuery<>(entityManager, criteriaBuilderFactory)
.from(QInventory.inventory)
.select(Projections.constructor(AggregatedInventoryQuantity.class, QInventory.inventory.accession().id,
QInventory.inventory.formTypeCode,
QInventory.inventory.availabilityStatusCode,
QInventory.inventory.quantityOnHandUnitCode,
QInventory.inventory.inventoryMaintenancePolicy().id.countDistinct().as("inventoryMaintenancePolicyCount"),
QInventory.inventory.parentInventory().id.countDistinct().as("parentInventoryCount"),
QInventory.inventory.id.count().as("inventoryCount"),
QInventory.inventory.quantityOnHand.sum().as("quantityOnHand")
))
// where
.where(filters)
// group by
.groupBy(groupByProperties);
// get total elements
var stopWatch = StopWatch.createStarted();
var totalElements = aggQuery.fetchCount();
stopWatch.split();
log.warn("aggregateQuantity count took {}ms", stopWatch.getTime(TimeUnit.MILLISECONDS));
stopWatch.unsplit();
// apply pagination
aggQuery.offset(page.getOffset()).limit(page.getPageSize());
// apply sorting
for (Sort.Order o : page.getSort()) {
if (StringUtils.equalsIgnoreCase(QAccession.accession.id.toString(), o.getProperty())) {
// sort by accession.id
aggQuery.orderBy(new OrderSpecifier<>(o.isAscending() ? Order.ASC : Order.DESC, ExpressionUtils.path(String.class, o.getProperty())));
} else {
aggQuery.orderBy(new OrderSpecifier<>(o.isAscending() ? Order.ASC : Order.DESC, ExpressionUtils.path(String.class, o.getProperty())));
}
}
var content = aggQuery.fetch();
stopWatch.split();
log.warn("aggregateQuantity fetch took {}ms", stopWatch.getTime(TimeUnit.MILLISECONDS));
return new PageImpl<>(content, page, totalElements);
}
}