package com.kucun.Service;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
import javax.persistence.EntityNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import com.kucun.data.entity.*;
import com.kucun.dataDo.*;
@Service
public class AppService {
// 自动注入所有依赖
@Autowired private KucunRepository kucunRepository;
@Autowired private DynamicRepositoryService repositoryService;
@Autowired private EntityDependencyService dependencyService;
/**
* 获取所有实体类型的数据
* @return 包含所有实体数据的Map
*/
public Information getAllData() {
Map<String, Object> response = new HashMap<>();
repositoryService.getRepositoryNameMap().forEach((key, repo) ->
response.put(key + "s", repo.findAll())
);
return Information.NewSuccess(response);
}
/**
* 获取指定实体类型的所有数据
* @param entityName 实体名称
* @return 实体数据列表
*/
public Information getEntityData(String entityName) {
JpaRepository<?, ?> repo = repositoryService.getJpaRepository(entityName);
return Information.NewSuccess(repo.findAll());
}
/**
* 添加新实体
* @param entity 要添加的实体对象
* @return 添加结果
*/
public Information addEntity(Object entity) {
try {
// 处理关联字段
handleAssociations(entity);
// 获取对应的Repository并保存
JpaRepository<Object, Serializable> repo =
(JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entity.getClass());
Object savedEntity = repo.save(entity);
// 如果是板材,初始化库存
if (savedEntity instanceof Bancai) {
initializeKucunForBancai((Bancai) savedEntity);
}
return Information.NewSuccess(savedEntity);
} catch (Exception ex) {
return Information.Newfail(500, "创建失败: " + ex.getMessage(), null);
}
}
/**
* 更新实体
* @param entity 包含ID的实体对象
* @return 更新结果
*/
public Information updateEntity(Object entity) {
if (entity == null) {
return Information.Newfail(403, "参数为空", null);
}
try {
// 获取ID字段
Field idField = entity.getClass().getDeclaredField("id");
idField.setAccessible(true);
Object idValue = idField.get(entity);
if (idValue == null) {
return Information.Newfail(403, "ID为空", null);
}
// 获取Repository和现有实体
JpaRepository<Object, Serializable> repo =
(JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entity.getClass());
Object existingEntity = repo.findById((Serializable) idValue)
.orElseThrow(() -> new RuntimeException("实体不存在"));
// 复制非空属性并保存
copyNonNullProperties(entity, existingEntity);
return Information.NewSuccess(repo.save(existingEntity));
} catch (Exception ex) {
return Information.Newfail(500, "更新失败: " + ex.getMessage(), null);
}
}
/**
* 删除实体
* @param entity 要删除的实体
* @return 删除结果
*/
public Information deleteEntity(EntityBasis entity) {
if (entity == null) {
return Information.NewFail("删除对象不能为空");
}
try {
String entityName = entity.getClass().getSimpleName().toLowerCase();
JpaRepository<Object, Serializable> repo =
(JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entityName);
// 先加载完整实体(关键步骤)
Object fullEntity = repo.findById(entity.getId())
.orElseThrow(() -> new EntityNotFoundException("实体不存在"));
System.out.println("// 获得实体");
if(entity instanceof Bancai) {
if(((Bancai)fullEntity).getKucun()!=null&&((Bancai)fullEntity).getKucun().getShuliang()>0) {
return Information.NewFail("库存不为零,无法删除");
}
}
System.out.println("// 检查库存");
// 检查依赖关系
if (dependencyService.hasDependencies(entity.getClass(), entity.getId())) {
return Information.NewFail("该记录已被引用,无法删除");
}
System.out.println("// 检查依赖关系");
// 使用实体对象删除(触发级联操作)
repo.delete(fullEntity);
return Information.NewSuccess("删除成功");
} catch (Exception e) {
return Information.NewFail("删除错误: " + e.getMessage());
}
}
/**
* 动态查询实体
* @param entity 包含查询条件的实体对象
* @return 查询结果
*/
public <T> Information queryEntity(T entity) {
if (entity == null) {
return Information.NewFail("查询参数不能为空");
}
try {
JpaRepository<T, ?> repo = (JpaRepository<T, ?>) repositoryService.getJpaRepository(entity.getClass());
Example<T> example = Example.of(entity, ExampleMatcher.matching()
.withIgnoreNullValues()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING));
return Information.NewSuccess(repo.findAll(example));
} catch (Exception e) {
return Information.NewFail("查询失败: " + e.getMessage());
}
}
// ====================== 私有辅助方法 ======================
/**
* 为板材初始化库存
* @param bancai 板材对象
*/
private void initializeKucunForBancai(Bancai bancai) throws Exception {
Kucun kucun = new Kucun(null, bancai, 0);
bancai.setKucun(kucunRepository.save(kucun));
}
/**
* 处理实体关联关系
* @param entity 要处理的实体
*/
private void handleAssociations(Object entity) throws Exception {
for (Field field : entity.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object value = field.get(entity);
if (value == null) continue;
// 处理 JPA 实体关联
if (value instanceof EntityBasis) {
EntityBasis associated = (EntityBasis) value;
JpaRepository<Object, Serializable> repo =
(JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(associated.getClass().getSimpleName().toLowerCase());
// 只处理已存在实体(不创建新关联)
if (associated.getId() != null) {
Object managedEntity = repo.findById(associated.getId())
.orElseThrow(() -> new RuntimeException("关联实体不存在"));
field.set(entity, managedEntity);
}
}
// 处理集合关联
else if (value instanceof Collection) {
List<Object> managedEntities = new ArrayList<>();
for (Object item : (Collection<?>) value) {
if (item instanceof EntityBasis) {
EntityBasis eb = (EntityBasis) item;
JpaRepository<Object, Serializable> repo =
(JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(eb.getClass().getSimpleName().toLowerCase());
if (eb.getId() != null) {
managedEntities.add(repo.findById(eb.getId())
.orElseThrow(() -> new RuntimeException("关联实体不存在")));
}
}
}
if (!managedEntities.isEmpty()) {
field.set(entity, managedEntities);
}
}
}
}
/**
* 复制非空属性
* @param source 源对象
* @param target 目标对象
*/
private void copyNonNullProperties(Object source, Object target) throws IllegalAccessException {
for (Field field : source.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object value = field.get(source);
// 跳过关联字段和ID字段
if (value != null &&
!(value instanceof EntityBasis) &&
!(value instanceof Collection) &&
!field.getName().equals("id")) {
try {
Field targetField = target.getClass().getDeclaredField(field.getName());
targetField.setAccessible(true);
targetField.set(target, value);
} catch (NoSuchFieldException ignored) {}
}
}
}
}删除错误: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"2025-06-17 14:05:00.014 INFO 6936 --- [nio-8080-exec-3] o.a.c.c.C.[.[localhost].[/KuCun2] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-06-17 14:05:00.014 INFO 6936 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2025-06-17 14:05:00.014 DEBUG 6936 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2025-06-17 14:05:00.032 DEBUG 6936 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2025-06-17 14:05:00.034 INFO 6936 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed initialization in 20 ms
2025-06-17 14:05:00.065 DEBUG 6936 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : POST "/KuCun2/app/delete/bancai", parameters={}
2025-06-17 14:05:00.085 DEBUG 6936 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.kucun.controller.AppController#deleteEntity(String, Map)
2025-06-17 14:05:00.199 DEBUG 6936 --- [nio-8080-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [{id=9}]
2025-06-17 14:05:00.333 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : select bancai0_.id as id1_0_0_, bancai0_.caizhi_id as caizhi_i3_0_0_, bancai0_.houdu as houdu2_0_0_, bancai0_.kucun_id as kucun_id4_0_0_, bancai0_.mupi1_id as mupi5_0_0_, bancai0_.mupi2_id as mupi6_0_0_ from bancai bancai0_ where bancai0_.id=?
Hibernate: select bancai0_.id as id1_0_0_, bancai0_.caizhi_id as caizhi_i3_0_0_, bancai0_.houdu as houdu2_0_0_, bancai0_.kucun_id as kucun_id4_0_0_, bancai0_.mupi1_id as mupi5_0_0_, bancai0_.mupi2_id as mupi6_0_0_ from bancai bancai0_ where bancai0_.id=?
// 获得实体
// 检查库存
2025-06-17 14:05:00.391 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : select count(chanpin_zu0_.id) as col_0_0_ from chanpin_zujian chanpin_zu0_ where chanpin_zu0_.bancai_id=?
Hibernate: select count(chanpin_zu0_.id) as col_0_0_ from chanpin_zujian chanpin_zu0_ where chanpin_zu0_.bancai_id=?
2025-06-17 14:05:00.399 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : select count(dingdan_ch0_.id) as col_0_0_ from dingdan_chanpin_zujian dingdan_ch0_ where dingdan_ch0_.bancai_id=?
Hibernate: select count(dingdan_ch0_.id) as col_0_0_ from dingdan_chanpin_zujian dingdan_ch0_ where dingdan_ch0_.bancai_id=?
2025-06-17 14:05:00.402 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : select count(kucun0_.id) as col_0_0_ from kucun kucun0_ where kucun0_.bancai_id=?
Hibernate: select count(kucun0_.id) as col_0_0_ from kucun kucun0_ where kucun0_.bancai_id=?
2025-06-17 14:05:00.405 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : select count(jinhuo0_.id) as col_0_0_ from jinhuo jinhuo0_ where jinhuo0_.bancai_id=?
Hibernate: select count(jinhuo0_.id) as col_0_0_ from jinhuo jinhuo0_ where jinhuo0_.bancai_id=?
// 检查依赖关系
2025-06-17 14:05:00.429 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : select caizhi0_.id as id1_1_0_, caizhi0_.name as name2_1_0_ from caizhi caizhi0_ where caizhi0_.id=?
Hibernate: select caizhi0_.id as id1_1_0_, caizhi0_.name as name2_1_0_ from caizhi caizhi0_ where caizhi0_.id=?
2025-06-17 14:05:00.448 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : select mupi0_.id as id1_9_0_, mupi0_.name as name2_9_0_, mupi0_.you as you3_9_0_ from mupi mupi0_ where mupi0_.id=?
Hibernate: select mupi0_.id as id1_9_0_, mupi0_.name as name2_9_0_, mupi0_.you as you3_9_0_ from mupi mupi0_ where mupi0_.id=?
2025-06-17 14:05:00.479 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : delete from bancai where id=?
Hibernate: delete from bancai where id=?
2025-06-17 14:05:00.483 DEBUG 6936 --- [nio-8080-exec-3] org.hibernate.SQL : delete from caizhi where id=?
Hibernate: delete from caizhi where id=?
2025-06-17 14:05:00.505 WARN 6936 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1451, SQLState: 23000
2025-06-17 14:05:00.505 ERROR 6936 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : Cannot delete or update a parent row: a foreign key constraint fails (`stock`.`bancai`, CONSTRAINT `FKaqqiwbo1buldyylxfd10t6s9i` FOREIGN KEY (`caizhi_id`) REFERENCES `caizhi` (`id`))
2025-06-17 14:05:00.506 INFO 6936 --- [nio-8080-exec-3] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2025-06-17 14:05:00.565 DEBUG 6936 --- [nio-8080-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
2025-06-17 14:05:00.566 DEBUG 6936 --- [nio-8080-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Writing [com.kucun.data.entity.Information@56c5a0dc]
2025-06-17 14:05:00.582 DEBUG 6936 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK
最新发布