zhou zhou
1 天以前 691bee4229856f8bf81c2720092ecee1c9f21509
#getter$摘出entity
1个文件已修改
330 ■■■■ 已修改文件
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/buildPageRowsUtils.java 330 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/buildPageRowsUtils.java
@@ -14,13 +14,11 @@
import com.vincent.rsf.server.manager.entity.Companys;
import com.vincent.rsf.server.manager.entity.Warehouse;
import com.vincent.rsf.server.manager.entity.WarehouseAreas;
import com.vincent.rsf.server.manager.service.CompanysService;
import com.vincent.rsf.server.manager.service.WarehouseService;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.system.constant.DictTypeCode;
import com.vincent.rsf.server.system.entity.DictData;
import com.vincent.rsf.server.system.entity.User;
import com.vincent.rsf.server.system.service.DictDataService;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.service.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -45,27 +43,35 @@
    private static final String USER_NAME_CACHE_FLAG = "PAGE_ROWS_USER_NAME";
    private static final String WAREHOUSE_NAME_CACHE_FLAG = "PAGE_ROWS_WAREHOUSE_NAME";
    private static final String COMPANY_NAME_CACHE_FLAG = "PAGE_ROWS_COMPANY_NAME";
    private static final String DICT_LABEL_CACHE_FLAG = "PAGE_ROWS_DICT_LABEL";
    private static final String ENTITY_FIELD_CACHE_FLAG = "PAGE_ROWS_ENTITY_FIELD";
    private static final int NAME_CACHE_TTL_SECONDS = 300;
    private static final Consumer<List<Object>> NO_OP_ENRICHER = records -> {
    };
    private static final List<IdFieldMapping> COMMON_ID_FIELD_MAPPINGS = List.of(
            new IdFieldMapping("tenantId", "tenantId$", com.vincent.rsf.server.system.service.TenantService.class, "name"),
            new IdFieldMapping("deptId", "deptId$", com.vincent.rsf.server.system.service.DeptService.class, "name"),
            new IdFieldMapping("dictTypeId", "dictTypeId$", com.vincent.rsf.server.system.service.DictTypeService.class, "name"),
            new IdFieldMapping("tenantId", "tenantId$", TenantService.class, "name"),
            new IdFieldMapping("deptId", "deptId$", DeptService.class, "name"),
            new IdFieldMapping("dictTypeId", "dictTypeId$", DictTypeService.class, "name"),
            new IdFieldMapping("userId", "userId$", UserService.class, "nickname"),
            new IdFieldMapping("root", "root$", UserService.class, "username"),
            new IdFieldMapping("warehouseId", "warehouseId$", WarehouseService.class, "name"),
            new IdFieldMapping("warehouse", "warehouse$", WarehouseService.class, "name"),
            new IdFieldMapping("area", "area$", com.vincent.rsf.server.manager.service.WarehouseAreasService.class, "name"),
            new IdFieldMapping("areaId", "areaId$", com.vincent.rsf.server.manager.service.WarehouseAreasService.class, "name"),
            new IdFieldMapping("area", "area$", WarehouseAreasService.class, "name"),
            new IdFieldMapping("areaId", "areaId$", WarehouseAreasService.class, "name"),
            new IdFieldMapping("shipperId", "shipperId$", CompanysService.class, "name"),
            new IdFieldMapping("supplierId", "supplierId$", CompanysService.class, "name"),
            new IdFieldMapping("splrId", "splrId$", CompanysService.class, "name"),
            new IdFieldMapping("groupId", "groupId$", com.vincent.rsf.server.manager.service.MatnrGroupService.class, "name"),
            new IdFieldMapping("locId", "locId$", com.vincent.rsf.server.manager.service.LocService.class, "code"),
            new IdFieldMapping("locTypeId", "locTypeId$", com.vincent.rsf.server.manager.service.LocTypeService.class, "name")
            new IdFieldMapping("groupId", "groupId$", MatnrGroupService.class, "name"),
            new IdFieldMapping("locId", "locId$", LocService.class, "code"),
            new IdFieldMapping("locTypeId", "locTypeId$", LocTypeService.class, "name")
    );
    private static final Map<Class<?>, Consumer<List<Object>>> SPECIAL_RECORD_ENRICHERS = createSpecialRecordEnrichers();
    private static final Map<Class<?>, Consumer<List<Object>>> RESOLVED_ENRICHER_CACHE = new ConcurrentHashMap<>();
    private static final Map<Class<?>, List<IdFieldMapping>> APPLICABLE_ID_FIELD_MAPPINGS_CACHE = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Map<String, Optional<Field>>> FIELD_CACHE = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Optional<Field>> ID_FIELD_CACHE = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Map<String, String>> COLUMN_CACHE = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Optional<IService<?>>> SERVICE_CACHE = new ConcurrentHashMap<>();
    public static <T> T rowsMap(T data) {
        if (data == null) {
@@ -172,7 +178,7 @@
    }
    private static void rowsMapByClass(Class<?> recordClass, List<Object> records) {
        if (recordClass == null || Cools.isEmpty(records)) {
        if (recordClass == null || Cools.isEmpty(records) || isSimpleValueType(recordClass)) {
            return;
        }
        if (WarehouseAreas.class.isAssignableFrom(recordClass)) {
@@ -182,7 +188,7 @@
            return;
        }
        userNameMap(records);
        applyCommonIdFieldMappings(records);
        applyCommonIdFieldMappings(recordClass, records);
        Consumer<List<Object>> enricher = findSpecialRecordEnricher(recordClass);
        if (enricher != null) {
            enricher.accept(records);
@@ -190,8 +196,8 @@
        fillUserRoleIds(records);
    }
    private static void applyCommonIdFieldMappings(List<Object> records) {
        for (IdFieldMapping mapping : COMMON_ID_FIELD_MAPPINGS) {
    private static void applyCommonIdFieldMappings(Class<?> recordClass, List<Object> records) {
        for (IdFieldMapping mapping : getApplicableIdFieldMappings(recordClass)) {
            fillFieldById(records, mapping.sourceField(), mapping.targetField(), mapping.serviceClass(), mapping.returnField());
        }
    }
@@ -294,12 +300,17 @@
    }
    private static Consumer<List<Object>> findSpecialRecordEnricher(Class<?> recordClass) {
        Consumer<List<Object>> enricher = RESOLVED_ENRICHER_CACHE.computeIfAbsent(recordClass, buildPageRowsUtils::resolveSpecialRecordEnricher);
        return enricher == NO_OP_ENRICHER ? null : enricher;
    }
    private static Consumer<List<Object>> resolveSpecialRecordEnricher(Class<?> recordClass) {
        for (Map.Entry<Class<?>, Consumer<List<Object>>> entry : SPECIAL_RECORD_ENRICHERS.entrySet()) {
            if (entry.getKey().isAssignableFrom(recordClass)) {
                return entry.getValue();
            }
        }
        return null;
        return NO_OP_ENRICHER;
    }
    private static void fillWkOrderRows(List<Object> records) {
@@ -531,9 +542,6 @@
            userRoleMap.computeIfAbsent(userId, key -> new ArrayList<>()).add(roleId);
        }
        for (Object record : records) {
            if (!hasField(record, "userRoleIds")) {
                continue;
            }
            Long userId = readLongId(record, "id");
            List<Long> roleIds = userId == null ? Collections.emptyList() : userRoleMap.getOrDefault(userId, Collections.emptyList());
            writeField(record, "userRoleIds", roleIds.toArray(Long[]::new));
@@ -556,9 +564,6 @@
            return;
        }
        for (Object record : records) {
            if (!hasField(record, targetField)) {
                continue;
            }
            writeStringField(record, targetField, valueMap.get(readLongId(record, sourceField)));
        }
    }
@@ -567,24 +572,19 @@
        if (serviceClass == null || Cools.isEmpty(ids) || Cools.isEmpty(returnField)) {
            return Collections.emptyMap();
        }
        RedisService redisService = getRedisService();
        String cacheFlag = buildEntityFieldCacheFlag(serviceClass, returnField);
        return loadValueMap(
                ids,
                id -> getCachedStringValue(redisService, id, cacheFlag),
                missingIds -> {
        IService<?> service = getServiceBean(serviceClass);
        if (service == null) {
            return Collections.emptyMap();
        }
        List<?> entities = service.listByIds(new ArrayList<>(ids));
        if (Cools.isEmpty(entities)) {
            return Collections.emptyMap();
        }
        Map<Long, String> valueMap = new HashMap<>();
        for (Object entity : entities) {
            Long id = readEntityId(entity);
            Object value = readFieldValue(entity, returnField);
            if (id == null || value == null) {
                continue;
            }
            valueMap.put(id, String.valueOf(value));
        }
        return valueMap;
                    return service == null ? Collections.emptyList() : service.listByIds(new ArrayList<>(missingIds));
                },
                buildPageRowsUtils::readEntityId,
                entity -> normalizeStringValue(readFieldValue(entity, returnField)),
                loadedValueMap -> cacheStringValues(redisService, loadedValueMap, cacheFlag)
        );
    }
    private static Long readEntityId(Object entity) {
@@ -599,44 +599,6 @@
            }
        }
        return getLongFieldValue(entity, "id");
    }
    public static String getDictLabel(String dictTypeCode, Object value) {
        if (Cools.isEmpty(dictTypeCode) || value == null || Cools.isEmpty(String.valueOf(value))) {
            return null;
        }
        Object dictData = getEntityByFields(
                DictDataService.class,
                DictData.class,
                Map.of(
                        "dictTypeCode", dictTypeCode,
                        "value", value
                )
        );
        return getStringFieldValue(dictData, "label");
    }
    public static String getDictLabelWithValue(String dictTypeCode, Object value) {
        String label = getDictLabel(dictTypeCode, value);
        if (label == null || value == null) {
            return null;
        }
        return value + "." + label;
    }
    public static List<Long> getDictIds(String dictTypeCode, Collection<?> values) {
        if (Cools.isEmpty(dictTypeCode) || Cools.isEmpty(values)) {
            return Collections.emptyList();
        }
        List<?> dictDataList = listEntitiesByFieldIn(DictDataService.class, DictData.class, "value", values,
                Map.of("dictTypeCode", dictTypeCode));
        if (Cools.isEmpty(dictDataList)) {
            return Collections.emptyList();
        }
        return dictDataList.stream()
                .map(item -> getLongFieldValue(item, "id"))
                .filter(Objects::nonNull)
                .toList();
    }
    private static Long readLongId(Object record, String fieldName) {
@@ -666,37 +628,40 @@
    private static Map<Long, String> loadUserNameMap(Set<Long> userIds) {
        RedisService redisService = getRedisService();
        return loadNameMap(
        UserService userService = getServiceBean(UserService.class, UserService.class);
        return loadValueMap(
                userIds,
                userId -> getCachedName(redisService, userId, USER_NAME_CACHE_FLAG),
                missingUserIds -> SpringUtils.getBean(UserService.class).listByIds(missingUserIds),
                userId -> getCachedStringValue(redisService, userId, USER_NAME_CACHE_FLAG),
                missingUserIds -> userService == null ? Collections.emptyList() : userService.listByIds(missingUserIds),
                User::getId,
                User::getNickname,
                loadedUserNameMap -> cacheNames(redisService, loadedUserNameMap, USER_NAME_CACHE_FLAG)
                loadedUserNameMap -> cacheStringValues(redisService, loadedUserNameMap, USER_NAME_CACHE_FLAG)
        );
    }
    private static Map<Long, String> loadWarehouseNameMap(Set<Long> warehouseIds) {
        RedisService redisService = getRedisService();
        return loadNameMap(
        WarehouseService warehouseService = getServiceBean(WarehouseService.class, WarehouseService.class);
        return loadValueMap(
                warehouseIds,
                id -> getCachedName(redisService, id, WAREHOUSE_NAME_CACHE_FLAG),
                missingIds -> SpringUtils.getBean(WarehouseService.class).listByIds(missingIds),
                id -> getCachedStringValue(redisService, id, WAREHOUSE_NAME_CACHE_FLAG),
                missingIds -> warehouseService == null ? Collections.emptyList() : warehouseService.listByIds(missingIds),
                Warehouse::getId,
                Warehouse::getName,
                loadedNameMap -> cacheNames(redisService, loadedNameMap, WAREHOUSE_NAME_CACHE_FLAG)
                loadedNameMap -> cacheStringValues(redisService, loadedNameMap, WAREHOUSE_NAME_CACHE_FLAG)
        );
    }
    private static Map<Long, String> loadCompanyNameMap(Set<Long> companyIds) {
        RedisService redisService = getRedisService();
        return loadNameMap(
        CompanysService companysService = getServiceBean(CompanysService.class, CompanysService.class);
        return loadValueMap(
                companyIds,
                id -> getCachedName(redisService, id, COMPANY_NAME_CACHE_FLAG),
                missingIds -> SpringUtils.getBean(CompanysService.class).listByIds(missingIds),
                id -> getCachedStringValue(redisService, id, COMPANY_NAME_CACHE_FLAG),
                missingIds -> companysService == null ? Collections.emptyList() : companysService.listByIds(missingIds),
                Companys::getId,
                Companys::getName,
                loadedNameMap -> cacheNames(redisService, loadedNameMap, COMPANY_NAME_CACHE_FLAG)
                loadedNameMap -> cacheStringValues(redisService, loadedNameMap, COMPANY_NAME_CACHE_FLAG)
        );
    }
@@ -704,73 +669,69 @@
        if (Cools.isEmpty(values) || Cools.isEmpty(dictTypeCode)) {
            return Collections.emptyMap();
        }
        List<String> normalizedValues = values.stream()
                .filter(value -> !Cools.isEmpty(value))
                .distinct()
                .toList();
        if (normalizedValues.isEmpty()) {
            return Collections.emptyMap();
        RedisService redisService = getRedisService();
        DictDataService dictDataService = getServiceBean(DictDataService.class, DictDataService.class);
        String cacheFlag = buildDictLabelCacheFlag(dictTypeCode);
        return loadValueMap(
                values,
                value -> getCachedStringValue(redisService, value, cacheFlag),
                missingValues -> {
                    if (dictDataService == null) {
                        return Collections.emptyList();
        }
        DictDataService dictDataService;
        try {
            dictDataService = SpringUtils.getBean(DictDataService.class);
        } catch (Exception ignored) {
            return Collections.emptyMap();
        }
        List<DictData> dictDataList = dictDataService.list(
                    return dictDataService.list(
                new LambdaQueryWrapper<DictData>()
                        .eq(DictData::getDictTypeCode, dictTypeCode)
                        .in(DictData::getValue, normalizedValues)
                                    .in(DictData::getValue, missingValues)
        );
        if (Cools.isEmpty(dictDataList)) {
            return Collections.emptyMap();
        }
        return dictDataList.stream()
                .filter(Objects::nonNull)
                .filter(item -> !Cools.isEmpty(item.getValue()) && item.getLabel() != null)
                .collect(Collectors.toMap(DictData::getValue, DictData::getLabel, (left, right) -> left));
                },
                DictData::getValue,
                DictData::getLabel,
                loadedLabelMap -> cacheStringValues(redisService, loadedLabelMap, cacheFlag)
        );
    }
    private static <E> Map<Long, String> loadNameMap(Set<Long> ids,
                                                     Function<Long, String> cacheGetter,
                                                     Function<List<Long>, List<E>> entityLoader,
                                                     Function<E, Long> idGetter,
                                                     Function<E, String> nameGetter,
                                                     Consumer<Map<Long, String>> cacheWriter) {
        if (Cools.isEmpty(ids)) {
    private static <K, E> Map<K, String> loadValueMap(Set<K> keys,
                                                      Function<K, String> cacheGetter,
                                                      Function<List<K>, List<E>> entityLoader,
                                                      Function<E, K> keyGetter,
                                                      Function<E, String> valueGetter,
                                                      Consumer<Map<K, String>> cacheWriter) {
        if (Cools.isEmpty(keys)) {
            return Collections.emptyMap();
        }
        List<Long> normalizedIds = ids.stream()
        List<K> normalizedKeys = keys.stream()
                .filter(Objects::nonNull)
                .distinct()
                .toList();
        if (normalizedIds.isEmpty()) {
        if (normalizedKeys.isEmpty()) {
            return Collections.emptyMap();
        }
        Map<Long, String> nameMap = new HashMap<>();
        List<Long> missingIds = new ArrayList<>();
        for (Long id : normalizedIds) {
            String cachedName = cacheGetter.apply(id);
            if (cachedName == null) {
                missingIds.add(id);
        Map<K, String> valueMap = new HashMap<>();
        List<K> missingKeys = new ArrayList<>();
        for (K key : normalizedKeys) {
            String cachedValue = cacheGetter.apply(key);
            if (cachedValue == null) {
                missingKeys.add(key);
                continue;
            }
            nameMap.put(id, cachedName);
            valueMap.put(key, cachedValue);
        }
        if (missingIds.isEmpty()) {
            return nameMap;
        if (missingKeys.isEmpty()) {
            return valueMap;
        }
        List<E> loadedEntities = entityLoader.apply(missingIds);
        List<E> loadedEntities = entityLoader.apply(missingKeys);
        if (loadedEntities == null) {
            return nameMap;
            return valueMap;
        }
        Map<Long, String> loadedNameMap = loadedEntities.stream()
        Map<K, String> loadedValueMap = loadedEntities.stream()
                .filter(Objects::nonNull)
                .filter(item -> idGetter.apply(item) != null && nameGetter.apply(item) != null)
                .collect(Collectors.toMap(idGetter, nameGetter, (left, right) -> left));
        nameMap.putAll(loadedNameMap);
        cacheWriter.accept(loadedNameMap);
        return nameMap;
                .map(item -> new java.util.AbstractMap.SimpleEntry<>(keyGetter.apply(item), valueGetter.apply(item)))
                .filter(item -> item.getKey() != null && item.getValue() != null)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (left, right) -> left));
        valueMap.putAll(loadedValueMap);
        cacheWriter.accept(loadedValueMap);
        return valueMap;
    }
    private static RedisService getRedisService() {
@@ -782,17 +743,22 @@
    }
    private static IService<?> getServiceBean(Class<?> serviceClass) {
        try {
            Object bean = SpringUtils.getBean(serviceClass);
            return bean instanceof IService<?> iService ? iService : null;
        } catch (Exception ignored) {
        if (serviceClass == null) {
            return null;
        }
        return SERVICE_CACHE.computeIfAbsent(serviceClass, key -> {
            try {
                Object bean = SpringUtils.getBean(key);
                return bean instanceof IService<?> iService ? Optional.of(iService) : Optional.empty();
            } catch (Exception ignored) {
                return Optional.empty();
            }
        }).orElse(null);
    }
    private static Object getEntityByFields(Class<?> serviceClass, Class<?> entityClass, Map<String, Object> conditions) {
        List<?> entityList = listEntitiesByFields(serviceClass, entityClass, conditions, false);
        return Cools.isEmpty(entityList) ? null : entityList.get(0);
    private static <T> T getServiceBean(Class<?> serviceClass, Class<T> targetType) {
        IService<?> serviceBean = getServiceBean(serviceClass);
        return targetType != null && targetType.isInstance(serviceBean) ? targetType.cast(serviceBean) : null;
    }
    private static List<?> listEntitiesByFieldIn(Class<?> serviceClass,
@@ -813,27 +779,16 @@
        return service.list((Wrapper) queryWrapper);
    }
    private static List<?> listEntitiesByFields(Class<?> serviceClass,
                                                Class<?> entityClass,
                                                Map<String, Object> conditions,
                                                boolean all) {
        if (serviceClass == null || entityClass == null || Cools.isEmpty(conditions)) {
            return Collections.emptyList();
    private static String resolveColumnName(Class<?> entityClass, String fieldName) {
        if (entityClass == null || Cools.isEmpty(fieldName)) {
            return fieldName;
        }
        IService<?> service = getServiceBean(serviceClass);
        if (service == null) {
            return Collections.emptyList();
        }
        QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
        conditions.forEach((fieldName, value) -> queryWrapper.eq(resolveColumnName(entityClass, fieldName), value));
        if (all) {
            return service.list((Wrapper) queryWrapper);
        }
        Object entity = service.getOne((Wrapper) queryWrapper, false);
        return entity == null ? Collections.emptyList() : Collections.singletonList(entity);
        return COLUMN_CACHE
                .computeIfAbsent(entityClass, key -> new ConcurrentHashMap<>())
                .computeIfAbsent(fieldName, key -> resolveColumnNameInternal(entityClass, key));
    }
    private static String resolveColumnName(Class<?> entityClass, String fieldName) {
    private static String resolveColumnNameInternal(Class<?> entityClass, String fieldName) {
        Field field = getCachedField(entityClass, fieldName);
        if (field == null) {
            return camelToSnake(fieldName);
@@ -847,6 +802,15 @@
            return stripColumnQuotes(tableField.value());
        }
        return camelToSnake(fieldName);
    }
    private static List<IdFieldMapping> getApplicableIdFieldMappings(Class<?> recordClass) {
        if (recordClass == null) {
            return Collections.emptyList();
        }
        return APPLICABLE_ID_FIELD_MAPPINGS_CACHE.computeIfAbsent(recordClass, key -> COMMON_ID_FIELD_MAPPINGS.stream()
                .filter(mapping -> hasField(key, mapping.sourceField()) && hasField(key, mapping.targetField()))
                .toList());
    }
    private static String stripColumnQuotes(String column) {
@@ -910,31 +874,39 @@
        }
    }
    private static String getCachedName(RedisService redisService, Long id, String cacheFlag) {
        if (redisService == null || id == null) {
    private static String getCachedStringValue(RedisService redisService, Object key, String cacheFlag) {
        if (redisService == null || key == null || Cools.isEmpty(cacheFlag)) {
            return null;
        }
        try {
            String value = redisService.getValue(cacheFlag, String.valueOf(id));
            String value = redisService.getValue(cacheFlag, String.valueOf(key));
            return Cools.isEmpty(value) ? null : value;
        } catch (Exception ignored) {
            return null;
        }
    }
    private static void cacheNames(RedisService redisService, Map<Long, String> nameMap, String cacheFlag) {
        if (redisService == null || Cools.isEmpty(nameMap)) {
    private static void cacheStringValues(RedisService redisService, Map<?, String> valueMap, String cacheFlag) {
        if (redisService == null || Cools.isEmpty(valueMap) || Cools.isEmpty(cacheFlag)) {
            return;
        }
        nameMap.forEach((id, name) -> {
            if (id == null || Cools.isEmpty(name)) {
        valueMap.forEach((key, value) -> {
            if (key == null || Cools.isEmpty(value)) {
                return;
            }
            try {
                redisService.setValue(cacheFlag, String.valueOf(id), name, NAME_CACHE_TTL_SECONDS);
                redisService.setValue(cacheFlag, String.valueOf(key), value, NAME_CACHE_TTL_SECONDS);
            } catch (Exception ignored) {
            }
        });
    }
    private static String buildDictLabelCacheFlag(String dictTypeCode) {
        return DICT_LABEL_CACHE_FLAG + "." + dictTypeCode;
    }
    private static String buildEntityFieldCacheFlag(Class<?> serviceClass, String returnField) {
        return ENTITY_FIELD_CACHE_FLAG + "." + serviceClass.getName() + "." + returnField;
    }
    private static <T> void fillUserNameFields(List<T> records, Map<Long, String> userNameMap) {
@@ -1015,8 +987,24 @@
        return findField(type, "id");
    }
    private static boolean hasField(Class<?> recordClass, String fieldName) {
        return recordClass != null && !Cools.isEmpty(fieldName) && getCachedField(recordClass, fieldName) != null;
    }
    private static boolean hasField(Object record, String fieldName) {
        return record != null && !Cools.isEmpty(fieldName) && getCachedField(record.getClass(), fieldName) != null;
        return record != null && hasField(record.getClass(), fieldName);
    }
    private static boolean isSimpleValueType(Class<?> type) {
        return type != null
                && (type.isPrimitive()
                || Number.class.isAssignableFrom(type)
                || CharSequence.class.isAssignableFrom(type)
                || Boolean.class.isAssignableFrom(type)
                || Character.class.isAssignableFrom(type)
                || Enum.class.isAssignableFrom(type)
                || java.util.Date.class.isAssignableFrom(type)
                || java.time.temporal.Temporal.class.isAssignableFrom(type));
    }
    private record IdFieldMapping(String sourceField, String targetField, Class<?> serviceClass, String returnField) {