diff --git a/ems-core/src/main/java/it/integry/ems/dto/EntityHierarchy.java b/ems-core/src/main/java/it/integry/ems/dto/EntityHierarchy.java index c99931dff8..947fd41e4c 100644 --- a/ems-core/src/main/java/it/integry/ems/dto/EntityHierarchy.java +++ b/ems-core/src/main/java/it/integry/ems/dto/EntityHierarchy.java @@ -95,7 +95,7 @@ public class EntityHierarchy { } - public static class Field { + public static class Field implements Cloneable { private java.lang.reflect.Field field; private PK primaryKey; private Identity identity; @@ -151,7 +151,9 @@ public class EntityHierarchy { return identity != null; } - public boolean isVarBinary() { return varBinary != null; } + public boolean isVarBinary() { + return varBinary != null; + } public PK getPrimaryKey() { return primaryKey; @@ -237,5 +239,33 @@ public class EntityHierarchy { public String getFieldName() { return fieldName; } + + @Override + public Field clone() { + try { + Field cloned = (Field) super.clone(); + + // java.lang.reflect.Field è final, quindi usiamo lo stesso riferimento + cloned.field = this.field; + + // Tutte le altre proprietà sono @interface (annotazioni) quindi immutabili + cloned.primaryKey = this.primaryKey; + cloned.identity = this.identity; + cloned.sqlField = this.sqlField; + cloned.importFromParent = this.importFromParent; + cloned.priority = this.priority; + cloned.objectStorage = this.objectStorage; + cloned.blob = this.blob; + cloned.clob = this.clob; + cloned.varBinary = this.varBinary; + + // String è immutabile + cloned.fieldName = this.fieldName; + + return cloned; + } catch (CloneNotSupportedException e) { + throw new RuntimeException("Errore durante la clonazione del Field", e); + } + } } } diff --git a/ems-core/src/main/java/it/integry/ems_model/base/EntityBase.java b/ems-core/src/main/java/it/integry/ems_model/base/EntityBase.java index a77669e459..ed2d6f888a 100644 --- a/ems-core/src/main/java/it/integry/ems_model/base/EntityBase.java +++ b/ems-core/src/main/java/it/integry/ems_model/base/EntityBase.java @@ -29,7 +29,6 @@ import it.integry.ems.sync.MultiDBTransaction.Connection; import it.integry.ems.utility.UtilityDebug; import it.integry.ems_model.annotation.*; import it.integry.ems_model.config.EmsRestConstants; -import it.integry.ems_model.db.ResultSetMapper; import it.integry.ems_model.exception.*; import it.integry.ems_model.resolver.PropertyTypeResolver; import it.integry.ems_model.resolver.SqlFieldHolder; @@ -45,6 +44,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; import org.springframework.util.ReflectionUtils; import org.xmlpull.v1.XmlPullParserException; @@ -459,7 +459,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter String wherePK; if ((getOperation() == OperationType.SUBSTITUTE || getOperation() == OperationType.DELETE_THEN_INSERT) && getOldPk() != null) { - wherePK = getWhereCondOldPk(); + wherePK = getWhereCondOldPk(null); } else { wherePK = getEntityHolder().getWherePK(this); } @@ -499,7 +499,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter if (!entity.getOnlyPkMaster() && entity.getOperation() == OperationType.SELECT_OBJECT) { where = getEntityHolder().getWhereCondFields(entity); } else if (entity.getOldPk() != null) { - where = entity.getWhereCondOldPk(); + where = entity.getWhereCondOldPk(null); } else { where = getEntityHolder().getWherePK(entity); } @@ -525,29 +525,23 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter whereConds = ""; } - String query; + final List rowEntityFields = getEntityHolder().getEntityFields(rowClass, EntityHierarchy.Field::isSqlField); + String wherePK; - - if ((entity.getOperation() == OperationType.SUBSTITUTE || entity.getOperation() == OperationType.DELETE_THEN_INSERT) && entity.getOldPk() != null) { - wherePK = entity.getWhereCondOldPk(); + wherePK = entity.getWhereCondOldPk(rowClass); } else { wherePK = getEntityHolder().getWherePK(entity); } - HashMap fieldToSqlMap = getEntityHolder().getColumnMap(rowClass, true); - String columnList = Joiner.on(",").withKeyValueSeparator(" as ").join(fieldToSqlMap); + String columnList = Joiner.on(",") + .join(rowEntityFields.stream() + .map(x -> x.getSqlField().value()) + .collect(Collectors.toList())); - query = "SELECT " + columnList + " FROM " + tableName + " WHERE " + wherePK + whereConds; - - PreparedStatement ps = connection.prepareStatement(query); - ps.setQueryTimeout(queryTimeoutSeconds); - ResultSet rs = ps.executeQuery(); - ResultSetMapper mapper = new ResultSetMapper(); - List entityRows = (List) mapper.mapResultSetToList(rs, rowClass); - rs.close(); - ps.close(); + String query = "SELECT " + columnList + " FROM " + tableName + " WHERE " + wherePK + whereConds; + List entityRows = UtilityDB.executeSimpleQueryDTO(connection, query, rowClass, queryTimeoutSeconds); return entityRows; } @@ -938,7 +932,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter EntityBase clonedEntity = (EntityBase) deepClone(); clonedEntity.setOnlyPkMaster(false); - final List childs = entityHolder.getEntityChildrenFields(getClass()); + final List childs = getEntityHolder().getEntityChildrenFields(getClass()); for (Field entityChildField : childs) { entityChildField.setAccessible(true); @@ -1562,7 +1556,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter if (getOldPk() != null) { updateSQL .append(" WHERE ") - .append(getWhereCondOldPk()); + .append(getWhereCondOldPk(null)); } else if (!whereCondData.isEmpty()) { updateSQL .append(" WHERE "); @@ -1611,42 +1605,6 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter String a = ""; } - - // OLD - -// List fields = getEntityHolder().getFields(this.getClass()); -// -// List campi = new ArrayList<>(); -// List where = new ArrayList<>(); -// -// -// Map mapLob = getFieldToUpdate(fields, campi, where); -// -// if (!campi.isEmpty()) { -// String sql = "UPDATE " + getTableName() + " SET " + StringUtils.join(campi, ","); -// -// -// if (getOldPk() != null) { -// whereCond = getWhereCondOldPk(); -// } else if (whereCond == null || (whereCond.split(" AND ").length != where.size() && !where.isEmpty())) { -// whereCond = StringUtils.join(where, " AND "); -// } -// -// sql += " WHERE " + whereCond; -// -// logger.trace("Query tracing: {}", sql); -// -// try { -// PreparedStatement pstm = connection.prepareStatement(sql); -// setupBinaryParams(mapLob, pstm); -// -// pstm.setQueryTimeout(queryTimeoutSeconds); -// pstm.executeUpdate(); -// pstm.close(); -// } catch (SQLException e) { -// throw new EntityException(e, this, sql); -// } -// } } public void setParentPKAndImportFromParent(EntityBase parent, Boolean isChild) throws InvocationTargetException, IllegalAccessException { @@ -1794,9 +1752,9 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter @JsonIgnore private String getWhereCondDelete() throws Exception { - Field[] fields = this.getClass().getDeclaredFields(); - List where = getPkWhereCond(fields, this); - String whereCondOldPk = getWhereCondOldPk(where); + List fields = getEntityHolder().getEntityFields(this.getClass(), null); + List where = getPkWhereCond(this, fields, null); + String whereCondOldPk = getWhereCondOldPk(where, null); String whereCondDel = ""; if (UtilityString.isNullOrEmpty(whereCondOldPk)) { if (whereCond != null) { @@ -1821,8 +1779,8 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter @JsonIgnore public String getPkWhereCond() throws IllegalAccessException { - Field[] fields = this.getClass().getDeclaredFields(); - List where = getPkWhereCond(fields, this); + List fields = getEntityHolder().getEntityFields(this.getClass(), null); + List where = getPkWhereCond(this, fields, null); if (whereCond == null) { whereCond = StringUtils.join(where, " AND "); @@ -1832,22 +1790,26 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter } - private List getPkWhereCond(Field[] fields, EntityBase parent) throws IllegalAccessException { - List where = new ArrayList(); + private List getPkWhereCond(EntityBase parent, List fields, Map parentToChildMappings) throws IllegalAccessException { + List where = new ArrayList<>(); - List listPK = Stream.of(fields).filter(x -> x.isAnnotationPresent(SqlField.class) && x.isAnnotationPresent(PK.class)).toList(); + @NotNull List listPK = fields.stream() + .filter(x -> x.isSqlField() && x.isPrimaryKey()) + .collect(Collectors.toList()); - for (Field field : listPK) { - field.setAccessible(true); - SqlField sqlField = field.getAnnotation(SqlField.class); - String sqlColumn = SqlFieldHolder.getSqlValue(sqlField.value(), field); + for (EntityHierarchy.Field field : listPK) { + SqlField sqlField = field.getSqlField(); - Object obj = field.get(parent); + String customMappingSqlField = parentToChildMappings != null ? parentToChildMappings.getOrDefault(field.getFieldName(), null) : null; + + String sqlColumn = SqlFieldHolder.getSqlValue(UtilityString.isNull(customMappingSqlField, sqlField.value()), field.getField()); + + Object obj = field.getField().get(parent); if (obj != null) { Object dato = SqlFieldHolder.getSqlValueFieldAsString(obj); where.add(sqlColumn + " = " + dato); } else if (this.getOperation() != OperationType.DELETE) { - where.add(sqlColumn + " IS null "); + where.add(sqlColumn + " IS NULL "); } } return where; @@ -1923,37 +1885,54 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter } @JsonIgnore - public String getWhereCondOldPk() throws IllegalAccessException, IOException, FieldMissingException { - Field[] fields = this.getClass().getDeclaredFields(); - List where = getPkWhereCond(fields, this); - return getWhereCondOldPk(where); + public String getWhereCondOldPk(Class entityRowClass) throws IllegalAccessException, IOException, FieldMissingException { + Map currentEntityToChildSqlMappings = null; + if (entityRowClass != null) { + final List rowEntityFields = getEntityHolder().getEntityFields(entityRowClass, EntityHierarchy.Field::isSqlField); + + currentEntityToChildSqlMappings = rowEntityFields.stream() + .filter(x -> x.isImportFromParent() && + (x.getImportFromParent().parentEntity() == EntityBase.class || + x.getImportFromParent().parentEntity().equals(this.getClass()))) + .collect(Collectors.toMap(x -> x.getImportFromParent().value(), x -> x.getSqlField().value())); + } + + List currentEntityFields = getEntityHolder().getEntityFields(this.getClass(), null); + List where = getPkWhereCond(this, currentEntityFields, currentEntityToChildSqlMappings); + + return getWhereCondOldPk(where, currentEntityToChildSqlMappings); } - private String getWhereCondOldPk(List where) throws FieldMissingException, IOException { - Field[] fields = this.getClass().getDeclaredFields(); - String whereCondOldPk = null; + private String getWhereCondOldPk(List where, Map parentToChildMappings) throws FieldMissingException, IOException { + List fields = getEntityHolder().getEntityFields(this.getClass(), null); + if (this.getOldPk() != null) { Set> map = this.getOldPk().entrySet(); for (Entry stringObjectEntry : map) { final String campo = stringObjectEntry.getKey(); - Optional fieldOptional = Stream.of(fields).filter(field -> field.getName().equalsIgnoreCase(campo) && field.getAnnotation(SqlField.class) != null).findFirst(); + java.util.Optional fieldOptional = fields.stream() + .filter(field -> field.getFieldName().equalsIgnoreCase(campo) && field.isSqlField()) + .findFirst(); if (fieldOptional.isEmpty()) { throw new FieldMissingException(campo); } - final String sqlField = SqlFieldHolder.getSqlValue(fieldOptional.get().getAnnotation(SqlField.class).value(), fieldOptional.get()); -// final String sqlField = fieldOptional.get().getAnnotation(SqlField.class).value(); + final EntityHierarchy.Field field = fieldOptional.get(); - Optional matchedField = Stream.of(where).filter(value -> value.toLowerCase().contains(sqlField.toLowerCase())).findFirst(); - if (matchedField.isPresent()) { - where.remove(matchedField.get()); - } + String customMappingSqlField = parentToChildMappings != null ? parentToChildMappings.getOrDefault(field.getFieldName(), null) : null; + final String sqlField = SqlFieldHolder.getSqlValue(UtilityString.isNull(customMappingSqlField, field.getSqlField().value()), field.getField()); + + java.util.Optional matchedField = where.stream() + .filter(value -> value.toLowerCase().contains(sqlField.toLowerCase())) + .findFirst(); + + matchedField.ifPresent(where::remove); Object valore = this.getOldPk().get(campo); - if ((fieldOptional.get().getType() == Date.class || fieldOptional.get().getType() == Timestamp.class) && valore instanceof String) { + if ((field.getField().getType() == Date.class || field.getField().getType() == Timestamp.class) && valore instanceof String) { valore = UtilityString.parseDate(valore.toString()); } Object valueSql = SqlFieldHolder.getSqlValueFieldAsString(valore); @@ -1961,7 +1940,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter } } - whereCondOldPk = StringUtils.join(where, " AND "); + String whereCondOldPk = StringUtils.join(where, " AND "); return whereCondOldPk; } diff --git a/ems-core/src/main/java/it/integry/ems_model/base/EntityPropertyHolder.java b/ems-core/src/main/java/it/integry/ems_model/base/EntityPropertyHolder.java index 877ed15b73..97084d141b 100644 --- a/ems-core/src/main/java/it/integry/ems_model/base/EntityPropertyHolder.java +++ b/ems-core/src/main/java/it/integry/ems_model/base/EntityPropertyHolder.java @@ -121,6 +121,8 @@ public class EntityPropertyHolder { } for (Field declaredField : declaredFields) { + declaredField.setAccessible(true); + analyzedFields.add(new EntityHierarchy.Field() .setField(declaredField) .setPrimaryKey(declaredField.getAnnotation(PK.class)) @@ -405,9 +407,9 @@ public class EntityPropertyHolder { public String getWherePK(EntityBase entity) throws IllegalAccessException { List where = new ArrayList<>(); - List fieldsPK = Stream.of(entity.getClass().getDeclaredFields()) + List fieldsPK = Arrays.stream(entity.getClass().getDeclaredFields()) .filter(y -> y.isAnnotationPresent(SqlField.class) && y.isAnnotationPresent(PK.class)) - .toList(); + .collect(Collectors.toList()); boolean pkIdentityNull = false; for (Field field : fieldsPK) { @@ -535,25 +537,6 @@ public class EntityPropertyHolder { return StringUtils.join(colList, ", "); } - @Deprecated - public HashMap getColumnMap(Class clazz, Boolean isSql) { - - HashBiMap fieldToSqlMap = - (HashBiMap) classMap.get(clazz.getSimpleName()); - - HashMap columnsMap = new HashMap(); - for (Field field : fieldToSqlMap.keySet()) { - String val = fieldToSqlMap.get(field); - if (!isSql) { - columnsMap.put(field.getName(), val); - } else { - columnsMap.put(val, val); - } - - } - return columnsMap; - } - @Deprecated public Field getRigaField(Class clazz) { List list = (List) classMap.get(clazz.getSimpleName() + "_DETAIL_ID"); diff --git a/ems-core/src/main/java/it/integry/ems_model/entity/DtbDoct.java b/ems-core/src/main/java/it/integry/ems_model/entity/DtbDoct.java index 287f8a1bdf..aac353784b 100644 --- a/ems-core/src/main/java/it/integry/ems_model/entity/DtbDoct.java +++ b/ems-core/src/main/java/it/integry/ems_model/entity/DtbDoct.java @@ -1672,13 +1672,13 @@ public class DtbDoct extends DtbBaseDocT implements EquatableEntityInterface