{"record":{"id":"78fd16a160fb5b55","repo":"macrozheng/mall-swarm","slug":"error","errorCode":null,"errorMessage":"创建产品出错:{}","messagePattern":"创建产品出错:(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mall-admin/src/main/java/com/macro/mall/service/impl/PmsProductServiceImpl.java","lineNumber":322,"sourceCode":"     * 建立和插入关系表操作\n     *\n     * @param dao       可以操作的dao\n     * @param dataList  要插入的数据\n     * @param productId 建立关系的id\n     */\n    private void relateAndInsertList(Object dao, List dataList, Long productId) {\n        try {\n            if (CollectionUtils.isEmpty(dataList)) return;\n            for (Object item : dataList) {\n                Method setId = item.getClass().getMethod(\"setId\", Long.class);\n                setId.invoke(item, (Long) null);\n                Method setProductId = item.getClass().getMethod(\"setProductId\", Long.class);\n                setProductId.invoke(item, productId);\n            }\n            Method insertList = dao.getClass().getMethod(\"insertList\", List.class);\n            insertList.invoke(dao, dataList);\n        } catch (Exception e) {\n            LOGGER.warn(\"创建产品出错:{}\", e.getMessage());\n            throw new RuntimeException(e.getMessage());\n        }\n    }\n\n}\n","sourceCodeStart":304,"sourceCodeEnd":328,"githubUrl":"https://github.com/macrozheng/mall-swarm/blob/04c442fe318356bae4445a109dde7af297ce1e84/mall-admin/src/main/java/com/macro/mall/service/impl/PmsProductServiceImpl.java#L304-L328","documentation":"relateAndInsertList uses reflection to reset each item's id, set productId, and call the DAO's insertList method while inserting child records (attributes, SKUs, etc.) for a product. Any reflection failure (NoSuchMethodException, IllegalAccessException), or any MyBatis/database failure while batch inserting, is caught and rethrown as a RuntimeException whose message is logged as '创建产品出错' (error creating product). Because it uses reflection, the original exception type and stack trace are lost, leaving only e.getMessage().","triggerScenarios":"Calling PmsProductServiceImpl.create, update, or handleUpdateSkuStockList when a related list item lacks setId/setProductId methods (wrong DTO type), or when MyBatis insertList fails (SQL error, duplicate key, null column, list too large for the DB statement limits).","commonSituations":"Mapping the wrong entity class into a related list during create/update; DB schema drift so a column no longer exists; inserting a batch exceeding DB size limits; product relation records violating constraints (e.g., duplicate SKU barcodes).","solutions":["Log the full exception with a stack trace instead of only e.getMessage(), and rerun create/update to see the real root cause.","Verify every object in the related list is the expected type with setId(Long), setProductId(Long), and that its DAO has insertList(List).","Check the database constraints/schema for the relation table (columns, unique keys, nullable fields) against the data being inserted.","Replace the reflection-based insertion with direct typed DAO calls so failures surface as compile-time and MyBatis errors.","Break very large related lists into smaller batches for insertList."],"exampleFix":"// before\ncatch (Exception e) {\n    LOGGER.warn(\"创建产品出错:{}\", e.getMessage());\n    throw new RuntimeException(e.getMessage());\n}\n// after\ncatch (Exception e) {\n    LOGGER.error(\"创建产品出错\", e);\n    throw new RuntimeException(\"插入产品关联数据失败: \" + e.getMessage(), e);\n}","handlingStrategy":"try-catch","validationCode":"// Before calling create/update, validate related lists and required product id\nif (CollectionUtils.isEmpty(product.getStepList())) { /* skip or fail fast */ }\nfor (Object item : allRelatedItems) {\n    try {\n        item.getClass().getMethod(\"setProductId\", Long.class);\n    } catch (NoSuchMethodException e) {\n        throw new IllegalArgumentException(\"Related item missing setProductId: \" + item.getClass());\n    }\n}","typeGuard":"boolean isRelatable(Object item) {\n    return item != null\n        && hasMethod(item, \"setId\", Long.class)\n        && hasMethod(item, \"setProductId\", Long.class);\n}\nprivate boolean hasMethod(Object o, String name, Class<?>... pts) {\n    try { o.getClass().getMethod(name, pts); return true; }\n    catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n    productComponentService.create(product);\n} catch (RuntimeException e) {\n    LOGGER.error(\"产品创建失败(关联数据插入)\", e);\n    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();\n    throw new MallException(\"产品关联数据插入失败，请检查关联列表与数据库约束\", e);\n}","preventionTips":["Always log the full exception with stack trace, not just getMessage().","Use typed DAO calls instead of reflection where possible to catch errors at compile time.","Validate related DTO types and required fields before create/update.","Run create/update inside a transaction so partial inserts roll back.","Add integration tests covering each relation list (attribute, SKU, steps) against a real schema."],"tags":["reflection","mybatis","database-insert","java"],"backgroundTag":"database-write-failed","analyzedSha":"04c442fe318356bae4445a109dde7af297ce1e84","analyzedAt":"2026-09-08T00:00:41.853Z","contentChangedAt":"2026-09-08T00:00:41.853Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}