Commit b950c370 authored by PECQUOT's avatar PECQUOT
Browse files

[fix] Cache rebuild after a referential import is now performed correctly (Mantis #49361)


[fix] Default analyst is now set after grid initialization (Mantis #49331)
[fix] Detection of perfect duplicates in grid algorithm reworked for performance (Mantis #50040)
[enh] Grid initialization is now capable to resume a previous initialization (Mantis #50045)
Signed-off-by: PECQUOT's avatarlp1ee9d <ludovic.pecquot@e-is.pro>
parent e4878826
## Sprint 79 - v3.8.0
- Une mise à jour de la base de données cliente HsqlDb s'exécutera au démarrage de l'application
## Sprint 78 - v3.7.5
- Pas de mise à jour de modèle
......
......@@ -171,7 +171,7 @@
<maven.compiler.debug>true</maven.compiler.debug>
<!-- Quadrige3 Core version -->
<quadrige3-core.version>3.6.0-SNAPSHOT</quadrige3-core.version>
<quadrige3-core.version>3.6.2</quadrige3-core.version>
<!-- Last ReefDb launcher version -->
<launcherVersion>3.0.3</launcherVersion>
......
......@@ -555,7 +555,7 @@ public class ReefDbTaxonNameDaoImpl extends TaxonNameDaoImpl implements ReefDbTa
String levelCode = (String) source.next();
String levelLabel = (String) source.next();
String levelName = (String) source.next();
Double levelNb = (Double) source.next();
Integer levelNb = (Integer) source.next();
Integer citationId = (Integer) source.next();
String citationName = (String) source.next();
......@@ -638,7 +638,7 @@ public class ReefDbTaxonNameDaoImpl extends TaxonNameDaoImpl implements ReefDbTa
result.setName((String) source.next());
//number
result.setNumber((Double) source.next());
result.setNumber((Integer) source.next());
return result;
......
......@@ -451,6 +451,26 @@ public class ReefDbBeans extends QuadrigeBeans {
return measurement == null || (measurement.getNumericalValue() == null && measurement.getQualitativeValue() == null);
}
public static Set<Integer> getPmfmIdsOfNonEmptyMeasurements(MeasurementAware bean) {
if (CollectionUtils.isNotEmpty(bean.getMeasurements())) {
return bean.getMeasurements().stream()
.filter(measurement -> !isMeasurementEmpty(measurement))
.map(measurement -> measurement.getPmfm().getId())
.collect(Collectors.toSet());
}
return new HashSet<>();
}
public static Set<Integer> getPmfmIdsOfNonEmptyIndividualMeasurements(MeasurementAware bean) {
if (CollectionUtils.isNotEmpty(bean.getIndividualMeasurements())) {
return bean.getIndividualMeasurements().stream()
.filter(measurement -> !isMeasurementEmpty(measurement))
.map(measurement -> measurement.getPmfm().getId())
.collect(Collectors.toSet());
}
return new HashSet<>();
}
public static final String PROPERTY_PMFM_ID = MeasurementDTO.PROPERTY_PMFM + '.' + PmfmDTO.PROPERTY_ID;
public static MeasurementDTO getMeasurementByPmfmId(MeasurementAware bean, int pmfmId) {
......@@ -467,6 +487,13 @@ public class ReefDbBeans extends QuadrigeBeans {
return null;
}
public static List<MeasurementDTO> getIndividualMeasurementsByPmfmId(MeasurementAware bean, int pmfmId) {
if (CollectionUtils.isNotEmpty(bean.getIndividualMeasurements())) {
return filterCollection(bean.getIndividualMeasurements(), measurement -> measurement.getPmfm().getId() == pmfmId);
}
return new ArrayList<>();
}
public static boolean haveSameMeasurements(Collection<MeasurementDTO> measurements, Collection<MeasurementDTO> otherMeasurements) {
List<Integer> pmfmIds = measurements.stream()
.filter(measurement -> !isMeasurementEmpty(measurement))
......
......@@ -221,7 +221,7 @@ public class PersistenceServiceImpl implements PersistenceService {
@Override
public void enableMassiveUpdate() {
if (!Daos.isFileDatabase(config.getJdbcUrl())) return;
if (!Daos.isHsqlFileDatabase(config.getJdbcUrl())) return;
if (LOG.isDebugEnabled()) {
LOG.debug("Enable massive update behavior [CHECKPOINT first]");
......@@ -242,7 +242,7 @@ public class PersistenceServiceImpl implements PersistenceService {
@Override
public void disableMassiveUpdate() {
if (!Daos.isFileDatabase(config.getJdbcUrl())) return;
if (!Daos.isHsqlFileDatabase(config.getJdbcUrl())) return;
if (LOG.isDebugEnabled()) {
LOG.debug("Disable massive update behavior [CHECKPOINT first]");
......@@ -315,7 +315,7 @@ public class PersistenceServiceImpl implements PersistenceService {
*/
private void shutdownDatabase() {
// Do not shutdown if database run as server
if (!Daos.isFileDatabase(config.getJdbcUrl())) {
if (!Daos.isHsqlFileDatabase(config.getJdbcUrl())) {
return;
}
......
......@@ -550,7 +550,7 @@ public class ReefDbUIContext extends ApplicationUIContext implements JAXXHelpUIH
// clear caches if forced OR if a post import action is needed
if (clearCache || isDbJustInstalled() || isDbJustImportedFromFile()) {
clearAllCaches();
clearCaches();
}
// Try to re authenticate
......@@ -605,43 +605,12 @@ public class ReefDbUIContext extends ApplicationUIContext implements JAXXHelpUIH
/**
* Clear all caches
*/
public void clearAllCaches() {
if (isPersistenceLoaded()) {
// clear DB cache
getPersistenceService().clearAllCaches();
// clear local cache
dataContext.resetLocalCache();
}
}
/**
* <p>reloadDbCache.</p>
*
* @param progressionModel a {@link ProgressionUIModel} object.
*/
public void reloadDbCache(ProgressionUIModel progressionModel) {
if (isPersistenceLoaded() && !isDbJustInstalled()) {
// save previous progression model state
int total = progressionModel.getTotal();
int current = progressionModel.getCurrent();
String message = progressionModel.getMessage();
// Clear first
clearAllCaches();
// reload all needed caches
getPersistenceService().loadDefaultCaches(progressionModel);
@Override
public void clearCaches() {
super.clearCaches();
// restore progression model
progressionModel.setTotal(total);
progressionModel.setCurrent(current);
progressionModel.setMessage(message);
}
// clear local cache also
dataContext.resetLocalCache();
}
/**
......
......@@ -24,7 +24,7 @@ package fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.gro
*/
import com.google.common.collect.Lists;
import fr.ifremer.quadrige3.ui.core.dto.QuadrigeBean;
import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO;
import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationAware;
import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO;
import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedRowModel;
......@@ -35,7 +35,8 @@ import java.util.Objects;
/**
* <p>OperationMeasurementsGroupedRowModel class.</p>
*/
public class OperationMeasurementsGroupedRowModel extends AbstractMeasurementsGroupedRowModel<QuadrigeBean, OperationMeasurementsGroupedRowModel>
public class OperationMeasurementsGroupedRowModel
extends AbstractMeasurementsGroupedRowModel<MeasurementDTO, OperationMeasurementsGroupedRowModel>
implements SamplingOperationAware {
/**
......@@ -74,13 +75,18 @@ public class OperationMeasurementsGroupedRowModel extends AbstractMeasurementsGr
}
@Override
public boolean isSameRow(AbstractMeasurementsGroupedRowModel that) {
public boolean isSameRow(AbstractMeasurementsGroupedRowModel<?, ?> that) {
if (!(that instanceof OperationMeasurementsGroupedRowModel)) return false;
return Objects.equals(this.getSamplingOperation(), ((OperationMeasurementsGroupedRowModel) that).getSamplingOperation()) && super.isSameRow(that);
}
@Override
public List<String> getDefaultProperties() {
return Lists.newArrayList(PROPERTY_SAMPLING_OPERATION, PROPERTY_TAXON_GROUP, PROPERTY_TAXON);
}
@Override
public String rowWithMeasurementsHashCode() {
return String.valueOf(getSamplingOperation() != null ? getSamplingOperation().getName() : null) + '|' + super.rowWithMeasurementsHashCode();
}
}
......@@ -50,13 +50,14 @@ import javax.swing.RowFilter;
import javax.swing.border.Border;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
/**
* Controleur pour les mesures des prelevements (ecran prelevements/mesure).
*/
public class OperationMeasurementsGroupedTableUIHandler
extends AbstractMeasurementsGroupedTableUIHandler<OperationMeasurementsGroupedRowModel, OperationMeasurementsGroupedTableUIModel, OperationMeasurementsGroupedTableUI> {
extends AbstractMeasurementsGroupedTableUIHandler<OperationMeasurementsGroupedRowModel, OperationMeasurementsGroupedTableUIModel, OperationMeasurementsGroupedTableUI> {
// editor for sampling operations column
private ExtendedComboBoxCellEditor<SamplingOperationDTO> samplingOperationCellEditor;
......@@ -68,10 +69,10 @@ public class OperationMeasurementsGroupedTableUIHandler
*/
public OperationMeasurementsGroupedTableUIHandler() {
super(OperationMeasurementsGroupedRowModel.PROPERTY_SAMPLING_OPERATION,
OperationMeasurementsGroupedRowModel.PROPERTY_TAXON_GROUP,
OperationMeasurementsGroupedRowModel.PROPERTY_TAXON,
OperationMeasurementsGroupedRowModel.PROPERTY_INDIVIDUAL_PMFMS,
OperationMeasurementsGroupedRowModel.PROPERTY_COMMENT);
OperationMeasurementsGroupedRowModel.PROPERTY_TAXON_GROUP,
OperationMeasurementsGroupedRowModel.PROPERTY_TAXON,
OperationMeasurementsGroupedRowModel.PROPERTY_INDIVIDUAL_PMFMS,
OperationMeasurementsGroupedRowModel.PROPERTY_COMMENT);
}
/**
......@@ -119,9 +120,9 @@ public class OperationMeasurementsGroupedTableUIHandler
// Set highlight border when selected (Mantis #48592)
toggleButton.setBorder(
toggleButton.isSelected()
? BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, getConfig().getColorHighlightButtonBorder()), initialToggleButtonBorder)
: initialToggleButtonBorder
toggleButton.isSelected()
? BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, getConfig().getColorHighlightButtonBorder()), initialToggleButtonBorder)
: initialToggleButtonBorder
);
}
......@@ -169,11 +170,11 @@ public class OperationMeasurementsGroupedTableUIHandler
@Override
public boolean include(Entry<? extends OperationMeasurementsGroupedTableModel, ? extends Integer> entry) {
return (getModel().getSamplingFilter() == null
|| getModel().getSamplingFilter().equals(entry.getValue(getTable().getColumnExt(OperationMeasurementsGroupedTableModel.SAMPLING).getModelIndex())))
&& (getModel().getTaxonGroupFilter() == null
|| getModel().getTaxonGroupFilter().equals(entry.getValue(getTable().getColumnExt(OperationMeasurementsGroupedTableModel.TAXON_GROUP).getModelIndex())))
&& (getModel().getTaxonFilter() == null
|| getModel().getTaxonFilter().equals(entry.getValue(getTable().getColumnExt(OperationMeasurementsGroupedTableModel.TAXON).getModelIndex())));
|| getModel().getSamplingFilter().equals(entry.getValue(getTable().getColumnExt(OperationMeasurementsGroupedTableModel.SAMPLING).getModelIndex())))
&& (getModel().getTaxonGroupFilter() == null
|| getModel().getTaxonGroupFilter().equals(entry.getValue(getTable().getColumnExt(OperationMeasurementsGroupedTableModel.TAXON_GROUP).getModelIndex())))
&& (getModel().getTaxonFilter() == null
|| getModel().getTaxonFilter().equals(entry.getValue(getTable().getColumnExt(OperationMeasurementsGroupedTableModel.TAXON).getModelIndex())));
}
});
}
......@@ -273,26 +274,32 @@ public class OperationMeasurementsGroupedTableUIHandler
// Colonne mnemonique
samplingOperationCellEditor = newExtendedComboBoxCellEditor(new ArrayList<>(), SamplingOperationDTO.class, false);
final TableColumnExt colonneMnemonique = addColumn(
samplingOperationCellEditor,
newTableCellRender(OperationMeasurementsGroupedTableModel.SAMPLING),
OperationMeasurementsGroupedTableModel.SAMPLING);
samplingOperationCellEditor,
newTableCellRender(OperationMeasurementsGroupedTableModel.SAMPLING),
OperationMeasurementsGroupedTableModel.SAMPLING);
colonneMnemonique.setCellEditor(samplingOperationCellEditor);
colonneMnemonique.setSortable(true);
setDefaultColumnMinWidth(colonneMnemonique);
if (getConfig().isDebugMode()) {
TableColumnExt indivIdCol = addColumn((ColumnIdentifier<OperationMeasurementsGroupedRowModel>) AbstractMeasurementsGroupedTableModel.INDIVIDUAL_ID);
indivIdCol.setSortable(true);
setDefaultColumnMinWidth(indivIdCol);
}
// Colonne groupe taxon
final TableColumnExt colTaxonGroup = addColumn(
taxonGroupCellEditor,
newTableCellRender(OperationMeasurementsGroupedTableModel.TAXON_GROUP),
OperationMeasurementsGroupedTableModel.TAXON_GROUP);
taxonGroupCellEditor,
newTableCellRender(OperationMeasurementsGroupedTableModel.TAXON_GROUP),
OperationMeasurementsGroupedTableModel.TAXON_GROUP);
colTaxonGroup.setSortable(true);
setDefaultColumnMinWidth(colTaxonGroup);
// Colonne taxon
final TableColumnExt colTaxon = addColumn(
taxonCellEditor,
newTableCellRender(OperationMeasurementsGroupedTableModel.TAXON),
OperationMeasurementsGroupedTableModel.TAXON);
taxonCellEditor,
newTableCellRender(OperationMeasurementsGroupedTableModel.TAXON),
OperationMeasurementsGroupedTableModel.TAXON);
colTaxon.setSortable(true);
setDefaultColumnMinWidth(colTaxon);
......@@ -304,9 +311,9 @@ public class OperationMeasurementsGroupedTableUIHandler
// Colonne analyste
final TableColumnExt colAnalyst = addColumn(
departmentCellEditor,
newTableCellRender(AbstractMeasurementsGroupedTableModel.ANALYST),
(ColumnIdentifier<OperationMeasurementsGroupedRowModel>) AbstractMeasurementsGroupedTableModel.ANALYST);
departmentCellEditor,
newTableCellRender(AbstractMeasurementsGroupedTableModel.ANALYST),
(ColumnIdentifier<OperationMeasurementsGroupedRowModel>) AbstractMeasurementsGroupedTableModel.ANALYST);
colAnalyst.setSortable(true);
setDefaultColumnMinWidth(colAnalyst);
......@@ -335,8 +342,8 @@ public class OperationMeasurementsGroupedTableUIHandler
super.installSortController();
getSortController().setComparator(
getTable().getColumnModel().getColumnExt(OperationMeasurementsGroupedTableModel.SAMPLING).getModelIndex(),
new SamplingOperationComparator()
getTable().getColumnModel().getColumnExt(OperationMeasurementsGroupedTableModel.SAMPLING).getModelIndex(),
new SamplingOperationComparator()
);
}
......@@ -370,6 +377,11 @@ public class OperationMeasurementsGroupedTableUIHandler
}
}
@Override
protected boolean isMeasurementNotEmpty(MeasurementDTO measurement) {
return !measurement.getPmfm().getId().equals(getModel().getTransitionLengthPmfmId()) && super.isMeasurementNotEmpty(measurement);
}
/**
* Initialize the data grid (see Mantis #34695)
*/
......@@ -377,7 +389,12 @@ public class OperationMeasurementsGroupedTableUIHandler
InitGridUI initGridUI = new InitGridUI(getUI());
InitGridUIModel initModel = initGridUI.getModel();
initModel.setSamplingOperations(getModel().getSamplingOperationsWithoutMeasurement());
initModel.setSamplingOperations(getModel().getSamplingOperations());
// set last sampling operation which has been input (use the last not sorted line of the model)
if (getModel().getRowCount() > 0) {
initModel.setLastSamplingOperation(getModel().getRows().get(getModel().getRowCount() - 1).getSamplingOperation());
}
if (getModel().getTransectOriginPmfmId() != null) {
initModel.setOriginPmfmId(getModel().getTransectOriginPmfmId());
......@@ -395,29 +412,22 @@ public class OperationMeasurementsGroupedTableUIHandler
if (initModel.isValid()) {
// init the grid and values
List<SamplingOperationDTO> samplingOperations = initModel.isAllSamplingOperations()
? initModel.getSamplingOperations()
: Collections.singletonList(initModel.getSamplingOperation());
List<OperationMeasurementsGroupedRowModel> rows = Lists.newArrayList();
int individualId = 0;
boolean isContiguous = initModel.isContiguousSamplingOperations();
int origin = initModel.getOrigin();
int lengthBySamplingOperation = isContiguous
? initModel.getLength() / samplingOperations.size()
: initModel.getLength();
int length = lengthBySamplingOperation;
for (SamplingOperationDTO samplingOperation : initModel.getResultMap().keySet()) {
AtomicInteger individualId = new AtomicInteger();
for (Integer transition : initModel.getResultMap().get(samplingOperation)) {
for (SamplingOperationDTO samplingOperation : samplingOperations) {
incrementNextIndividualId(samplingOperation, individualId);
for (int value = origin; value <= length; value += initModel.getTransition()) {
OperationMeasurementsGroupedRowModel row = getTableModel().createNewRow();
// Initialize the row
row.setSamplingOperation(samplingOperation);
// Affect individual pmfms from parent model
row.setIndividualPmfms(new ArrayList<>(getModel().getPmfms()));
// Set the individualId
row.setIndividualId(++individualId);
row.setIndividualId(individualId.get());
// Create empty measurements
ReefDbBeans.createEmptyMeasurements(row);
// Get the measurement
......@@ -426,28 +436,32 @@ public class OperationMeasurementsGroupedTableUIHandler
throw new ReefDbTechnicalException("No transition measurement found");
}
// Set its value and individualId
measurement.setNumericalValue(BigDecimal.valueOf(value));
measurement.setIndividualId(individualId);
measurement.setNumericalValue(BigDecimal.valueOf(transition));
measurement.setIndividualId(individualId.get());
row.setValid(true);
rows.add(row);
}
samplingOperation.setDirty(true);
if (isContiguous) {
origin += lengthBySamplingOperation;
length += lengthBySamplingOperation;
}
}
resetCellEditors();
getModel().addRows(rows);
getModel().setModify(true);
}
}
class SamplingOperationComparator implements Comparator<SamplingOperationDTO> {
private void incrementNextIndividualId(SamplingOperationDTO samplingOperation, AtomicInteger nextIndividualId) {
do {
nextIndividualId.incrementAndGet();
} while (getModel().getRows().stream().anyMatch(row ->
samplingOperation.equals(row.getSamplingOperation()) && nextIndividualId.get() == row.getIndividualId()));
}
static class SamplingOperationComparator implements Comparator<SamplingOperationDTO> {
AlphanumericComparator delegate;
SamplingOperationComparator() {
delegate = new AlphanumericComparator();
}
......
......@@ -36,7 +36,8 @@ import java.util.Objects;
/**
* Modele pour les mesures des prelevements (ecran prelevements/mesure).
*/
public class OperationMeasurementsGroupedTableUIModel extends AbstractMeasurementsGroupedTableUIModel<MeasurementDTO, OperationMeasurementsGroupedRowModel, OperationMeasurementsGroupedTableUIModel> {
public class OperationMeasurementsGroupedTableUIModel
extends AbstractMeasurementsGroupedTableUIModel<MeasurementDTO, OperationMeasurementsGroupedRowModel, OperationMeasurementsGroupedTableUIModel> {
/**
* Constant <code>PROPERTY_SAMPLING_OPERATION="samplingOperation"</code>
......@@ -87,7 +88,8 @@ public class OperationMeasurementsGroupedTableUIModel extends AbstractMeasuremen
getTransectOriginPmfmId() != null
&& getTransectLengthPmfmId() != null
&&*/ getTransitionLengthPmfmId() != null
&& !getSamplingOperationsWithoutMeasurement().isEmpty();
/* Mantis #50045: the grid initialisation is enabled even if there are measurements already inside
&& !getSamplingOperationsWithoutMeasurement().isEmpty()*/;
}
public List<SamplingOperationDTO> getSamplingOperationsWithoutMeasurement() {
......
......@@ -12,17 +12,18 @@ package fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.gro
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import com.google.common.collect.ImmutableList;
import fr.ifremer.reefdb.dto.ReefDbBeans;
import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO;
import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO;
......@@ -31,19 +32,22 @@ import jaxx.runtime.validator.swing.SwingValidator;
import org.apache.commons.collections4.CollectionUtils;
import org.nuiton.jaxx.application.swing.util.Cancelable;
import javax.annotation.Nonnull;
import javax.swing.JComponent;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.*;
import java.util.stream.Collectors;
import static org.nuiton.i18n.I18n.t;
/**
* <p>InitGridUIHandler class.</p>
*
*/
public class InitGridUIHandler extends AbstractReefDbUIHandler<InitGridUIModel, InitGridUI> implements Cancelable {
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
@Override
public void beforeInit(InitGridUI ui) {
super.beforeInit(ui);
......@@ -52,7 +56,9 @@ public class InitGridUIHandler extends AbstractReefDbUIHandler<InitGridUIModel,
ui.setContextValue(model);
}
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
@Override
public void afterInit(InitGridUI ui) {
initUI(ui);
......@@ -78,24 +84,31 @@ public class InitGridUIHandler extends AbstractReefDbUIHandler<InitGridUIModel,
} else if (InitGridUIModel.PROPERTY_SAMPLING_OPERATION.equals(evt.getPropertyName())) {
if (getModel().getSamplingOperation() != null) {
// try to get the values
// build existing transitions values map
buildCurrentMap(ImmutableList.of(getModel().getSamplingOperation()));
// Try to find the last transition gap and set it
getModel().setTransition(findLastTransition());
// find origin and length value
MeasurementDTO originMeasurement = ReefDbBeans.getMeasurementByPmfmId(getModel().getSamplingOperation(), getModel().getOriginPmfmId());
if (!ReefDbBeans.isMeasurementEmpty(originMeasurement) && getModel().getOriginUnit() != null) {
if (!ReefDbBeans.isMeasurementEmpty(originMeasurement) && getModel().getOriginUnit() != null && getModel().getTransitionUnit() != null) {
getModel().setOrigin(ReefDbBeans.convertLengthValue(
originMeasurement.getNumericalValue(),
getModel().getOriginUnit().getId(),
getModel().getTransitionUnit().getId()
originMeasurement.getNumericalValue(),
getModel().getOriginUnit().getId(),
getModel().getTransitionUnit().getId()
).intValue());
} else {
getModel().setOrigin(getConfig().getPitOriginDefaultValue());
}
MeasurementDTO lengthMeasurement = ReefDbBeans.getMeasurementByPmfmId(getModel().getSamplingOperation(), getModel().getLengthPmfmId());
if (!ReefDbBeans.isMeasurementEmpty(lengthMeasurement) && getModel().getLengthUnit() != null) {
if (!ReefDbBeans.isMeasurementEmpty(lengthMeasurement) && getModel().getLengthUnit() != null && getModel().getTransitionUnit() != null) {
getModel().setLength(ReefDbBeans.convertLengthValue(
lengthMeasurement.getNumericalValue(),