Spring-data-jpa报错Not an managed type: class java.lang.Object

在用spring-data-jpa 刚使用的时候,Tomcat启动报错

Caused by: java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object

仔细检查,发现

@Repository
public interface DeptDao extends JpaRepository{
}

JpaRepository后边缺少指定类型

正确的应该是

@Repository
public interface DeptDao extends JpaRepository<Dept,Long>{
}

6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server.服务器版本: Apache Tomcat/9.0.46 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 服务器构建: May 8 2021 17:35:52 UTC 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 服务器版本号: 9.0.46.0 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 操作系统名称: Windows 10 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: OS.版本: 10.0 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 架构: amd64 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Java 环境变量: C:\Program Files\Java\jdk-17 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Java虚拟机版本: 17.0.15+9-LTS-241 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: JVM.供应商: Oracle Corporation 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: CATALINA_BASE: D:\myeclipse\add\.metadata\.me_tcat9046 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: CATALINA_HOME: D:\myeclipse\plugins\com.genuitec.eclipse.server.embedded.tomcat.v90.core_13.0.0.v202405290550-me\tomcat9046 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcatalina.base=D:\myeclipse\add\.metadata\.me_tcat9046 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcatalina.home=D:\myeclipse\plugins\com.genuitec.eclipse.server.embedded.tomcat.v90.core_13.0.0.v202405290550-me\tomcat9046 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dwtp.deploy=D:\myeclipse\add\.metadata\.me_tcat9046\webapps 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Djava.library.path=C:\Program Files\Java\jdk-17\bin;D:\myeclipse\plugins\com.genuitec.eclipse.server.embedded.tomcat.v90.core_13.0.0.v202405290550-me\tomcat9046\bin 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dfile.encoding=UTF-8 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dstdout.encoding=UTF-8 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dstderr.encoding=UTF-8 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -XX:+ShowCodeDetailsInExceptionMessages 6月 29, 2025 8:01:40 下午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent 信息:java.library.path:[C:\Program Files\Java\jdk-17\bin;D:\myeclipse\plugins\com.genuitec.eclipse.server.embedded.tomcat.v90.core_13.0.0.v202405290550-me\tomcat9046\bin]上找不到基于APR的Apache Tomcat本机库,该库允许在生产环境中获得最佳性能 6月 29, 2025 8:01:40 下午 org.apache.coyote.AbstractProtocol init 信息: 初始化协议处理器 ["http-nio-8080"] 6月 29, 2025 8:01:40 下午 org.apache.coyote.AbstractProtocol init 信息: 初始化协议处理器 ["https-jsse-nio-8443"] 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.Catalina load 信息: 服务器在[787]毫秒内初始化 6月 29, 2025 8:01:40 下午 org.apache.catalina.core.StandardService startInternal 信息: 正在启动服务[Catalina] 6月 29, 2025 8:01:40 下午 org.apache.catalina.core.StandardEngine startInternal 信息: 正在启动 Servlet 引擎:[Apache Tomcat/9.0.46] 6月 29, 2025 8:01:40 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: 把web 应用程序部署到目录 [D:\myeclipse\add\.metadata\.me_tcat9046\webapps\docs] 6月 29, 2025 8:01:42 下午 org.apache.jasper.servlet.TldScanner scanJars 信息: 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 6月 29, 2025 8:01:42 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: Web应用程序目录[D:\myeclipse\add\.metadata\.me_tcat9046\webapps\docs]的部署已在[1,650]毫秒内完成 6月 29, 2025 8:01:42 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: 把web 应用程序部署到目录 [D:\myeclipse\add\.metadata\.me_tcat9046\webapps\examples] 6月 29, 2025 8:01:42 下午 org.apache.catalina.core.ApplicationContext log 信息: ContextListener: contextInitialized() 6月 29, 2025 8:01:42 下午 org.apache.catalina.core.ApplicationContext log 信息: SessionListener: contextInitialized() 6月 29, 2025 8:01:42 下午 org.apache.catalina.core.ApplicationContext log 信息: ContextListener: attributeAdded('StockTicker', 'async.Stockticker@1eeb9e5c') 6月 29, 2025 8:01:42 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: Web应用程序目录[D:\myeclipse\add\.metadata\.me_tcat9046\webapps\examples]的部署已在[281]毫秒内完成 6月 29, 2025 8:01:42 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: 把web 应用程序部署到目录 [D:\myeclipse\add\.metadata\.me_tcat9046\webapps\host-manager] 6月 29, 2025 8:01:42 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: Web应用程序目录[D:\myeclipse\add\.metadata\.me_tcat9046\webapps\host-manager]的部署已在[27]毫秒内完成 6月 29, 2025 8:01:42 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: 把web 应用程序部署到目录 [D:\myeclipse\add\.metadata\.me_tcat9046\webapps\KuCun2] 6月 29, 2025 8:01:46 下午 org.apache.jasper.servlet.TldScanner scanJars 信息: 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 6月 29, 2025 8:01:46 下午 org.apache.catalina.core.ApplicationContext log 信息: 2 Spring WebApplicationInitializers detected on classpath . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.3.12.RELEASE) 2025-06-29 20:01:46.968 INFO 15500 --- [ main] com.kucun.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT on DESKTOP-MN1QJ5M with PID 15500 (D:\myeclipse\add\.metadata\.me_tcat9046\webapps\KuCun2\WEB-INF\classes started by Admin in D:\myeclipse) 2025-06-29 20:01:46.973 INFO 15500 --- [ main] com.kucun.DemoApplication : No active profile set, falling back to default profiles: default 2025-06-29 20:01:47.836 INFO 15500 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2025-06-29 20:01:47.997 INFO 15500 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 147ms. Found 13 JPA repository interfaces. 2025-06-29 20:01:48.447 INFO 15500 --- [ main] o.a.c.c.C.[.[localhost].[/KuCun2] : Initializing Spring embedded WebApplicationContext 2025-06-29 20:01:48.447 INFO 15500 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1435 ms 2025-06-29 20:01:48.937 INFO 15500 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2025-06-29 20:01:49.055 INFO 15500 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.32.Final 2025-06-29 20:01:49.335 INFO 15500 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} 2025-06-29 20:01:49.560 INFO 15500 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2025-06-29 20:01:49.940 INFO 15500 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2025-06-29 20:01:49.972 INFO 15500 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect 2025-06-29 20:01:51.794 INFO 15500 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2025-06-29 20:01:51.809 INFO 15500 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2025-06-29 20:01:52.747 WARN 15500 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'appService': Unsatisfied dependency expressed through field 'repositoryService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dynamicRepositoryService': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customRepository' defined in com.kucun.dataDo.CustomRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object 2025-06-29 20:01:52.748 INFO 15500 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2025-06-29 20:01:52.750 INFO 15500 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2025-06-29 20:01:52.766 INFO 15500 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. 2025-06-29 20:01:52.773 INFO 15500 --- [ main] ConditionEvaluationReportLoggingListener : Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2025-06-29 20:01:52.807 ERROR 15500 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'appService': Unsatisfied dependency expressed through field 'repositoryService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dynamicRepositoryService': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customRepository' defined in com.kucun.dataDo.CustomRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1425) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:173) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:153) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:95) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172) ~[spring-web-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5161) ~[catalina.jar:9.0.46] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.46] at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717) ~[catalina.jar:9.0.46] at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690) ~[catalina.jar:9.0.46] at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:692) ~[catalina.jar:9.0.46] at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1184) ~[catalina.jar:9.0.46] at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1925) ~[catalina.jar:9.0.46] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-util.jar:9.0.46] at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123) ~[na:na] at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1094) ~[catalina.jar:9.0.46] at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:476) ~[catalina.jar:9.0.46] at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1611) ~[catalina.jar:9.0.46] at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:319) ~[catalina.jar:9.0.46] at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) ~[catalina.jar:9.0.46] at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) ~[catalina.jar:9.0.46] at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) ~[catalina.jar:9.0.46] at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:936) ~[catalina.jar:9.0.46] at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:829) ~[catalina.jar:9.0.46] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.46] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) ~[catalina.jar:9.0.46] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) ~[catalina.jar:9.0.46] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-util.jar:9.0.46] at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na] at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) ~[catalina.jar:9.0.46] at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) ~[catalina.jar:9.0.46] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.46] at org.apache.catalina.core.StandardService.startInternal(StandardService.java:433) ~[catalina.jar:9.0.46] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.46] at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930) ~[catalina.jar:9.0.46] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.46] at org.apache.catalina.startup.Catalina.start(Catalina.java:772) ~[catalina.jar:9.0.46] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342) ~[bootstrap.jar:9.0.46] at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473) ~[bootstrap.jar:9.0.46] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dynamicRepositoryService': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customRepository' defined in com.kucun.dataDo.CustomRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:415) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1791) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1307) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] ... 62 common frames omitted Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customRepository' defined in com.kucun.dataDo.CustomRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1799) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:624) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:612) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1243) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE] at com.kucun.Service.DynamicRepositoryService.init(DynamicRepositoryService.java:37) ~[classes/:0.0.1-SNAPSHOT] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] ... 74 common frames omitted Caused by: java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:582) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:85) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:75) ~[spring-data-jpa-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:229) ~[spring-data-jpa-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:179) ~[spring-data-jpa-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:162) ~[spring-data-jpa-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:72) ~[spring-data-jpa-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:310) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$4(RepositoryFactoryBeanSupport.java:294) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.util.Lazy.getNullable(Lazy.java:211) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.util.Lazy.get(Lazy.java:95) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144) ~[spring-data-jpa-2.3.9.RELEASE.jar:2.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1858) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1795) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] ... 91 common frames omitted List<Kucun> findByLastUpdatedAfter(Date date);
最新发布
06-30
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("实体不存在")); if(entity instanceof Bancai) { if(((Bancai)fullEntity).getKucun().getShuliang()>0) { return Information.NewFail("库存不为零,无法删除"); } } // 检查依赖关系 if (dependencyService.hasDependencies(entity.getClass(), entity.getId())) { return Information.NewFail("该记录已被引用,无法删除"); } // 使用实体对象删除(触发级联操作) 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) {} } } } }package com.kucun.controller; import com.fasterxml.jackson.databind.ObjectMapper; import com.kucun.Service.AppService; import com.kucun.data.entity.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.Collections; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/app") public class AppController { // Java 8 兼容的实体类型映射 private static final Map<String, Class<?>> ENTITY_MAP; static { Map<String, Class<?>> map = new HashMap<>(); map.put("user", User.class); map.put("bancai", Bancai.class); map.put("caizi", Caizhi.class); map.put("mupi", Mupi.class); map.put("dingdan", Dingdan.class); map.put("zujian", Zujian.class); map.put("chanpin", Chanpin.class); map.put("dingdan_chanpin", Dingdan_chanpin.class); map.put("dingdan_chanpin_zujian", Dingdan_chanpin_zujian.class); map.put("chanpin_zujian", Chanpin_zujian.class); map.put("jinhuo", Jinhuo.class); map.put("kucun", Kucun.class); ENTITY_MAP = Collections.unmodifiableMap(map); } @Autowired private AppService appService; @Autowired private ObjectMapper objectMapper; // ====================== 数据查询 ====================== @GetMapping("/all") public Information getAllData() { return appService.getAllData(); } @GetMapping("/all/{entityType}") public Information getEntityData(@PathVariable String entityType) { return appService.getEntityData(entityType.toLowerCase()); } // ====================== CRUD操作 ====================== @PostMapping("/add/{entityType}") public Information addEntity( @PathVariable String entityType, @RequestBody Map<String, Object> requestBody ) { return handleEntityOperation(entityType, requestBody, "add"); } @PostMapping("/select/{entityType}") public Information queryEntity( @PathVariable String entityType, @RequestBody Map<String, Object> requestBody ) { return handleEntityOperation(entityType, requestBody, "select"); } @PostMapping("/delete/{entityType}") public Information deleteEntity( @PathVariable String entityType, @RequestBody Map<String, Object> requestBody ) { return handleEntityOperation(entityType, requestBody, "delete"); } @PostMapping("/update/{entityType}") public Information updateEntity( @PathVariable String entityType, @RequestBody Map<String, Object> requestBody ) { return handleEntityOperation(entityType, requestBody, "update"); } // ====================== 核心辅助方法 ====================== private Information handleEntityOperation( String entityType, Map<String, Object> requestBody, String operation ) { String normalizedType = entityType.toLowerCase(); Class<?> entityClass = ENTITY_MAP.get(normalizedType); if (entityClass == null) { return Information.NewFail("不支持的实体类型: " + entityType); } try { Object entity = objectMapper.convertValue(requestBody, entityClass); switch (operation) { case "add": return appService.addEntity(entity); case "select": return appService.queryEntity(entity); case "delete": // 确保实体实现了EntityBasis接口 if (entity instanceof EntityBasis) { return appService.deleteEntity((EntityBasis) entity); } else { return Information.NewFail("删除操作需要实体实现EntityBasis接口"); } case "update": return appService.updateEntity(entity); default: return Information.NewFail("无效的操作类型"); } } catch (Exception e) { return Information.NewFail(operation + "操作失败: " + e.getMessage()); } } }package com.kucun.Service; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.metamodel.*; import org.springframework.stereotype.Service; import java.io.Serializable; import java.util.*; import java.util.stream.Collectors; @Service public class EntityDependencyService { @PersistenceContext private EntityManager entityManager; private final Map<Class<?>, Set<Attribute<?, ?>>> associationCache = new HashMap<>(); /** * 检查实体是否被其他实体引用 * @param entityClass 实体类 * @param entityId 实体ID * @return 存在引用返回true */ public boolean hasDependencies(Class<?> entityClass, Serializable entityId) { Metamodel metamodel = entityManager.getMetamodel(); Set<EntityType<?>> entities = metamodel.getEntities(); for (EntityType<?> entityType : entities) { // 跳过自身(避免自引用检查) if (entityType.getJavaType().equals(entityClass)) continue; Set<Attribute<?, ?>> associations = getAssociationAttributes(entityType); for (Attribute<?, ?> attr : associations) { if (attr.getJavaType().isAssignableFrom(entityClass)) { if (isReferenced(entityType, attr, entityId)) { return true; } } } } return false; } /** * 获取实体所有关联属性(带缓存) */ private Set<Attribute<?, ?>> getAssociationAttributes(EntityType<?> entityType) { return associationCache.computeIfAbsent(entityType.getJavaType(), k -> entityType.getAttributes().stream() .filter(Attribute::isAssociation) .collect(Collectors.toSet()) ); } /** * 检查特定关联是否引用目标实体 */ private boolean isReferenced(EntityType<?> entityType, Attribute<?, ?> attribute, Serializable targetId) { String jpql = buildReferenceQuery(entityType, attribute); Long count = (Long) entityManager.createQuery(jpql) .setParameter("targetId", targetId) .getSingleResult(); return count > 0; } /** * 构建引用检查查询 */ private String buildReferenceQuery(EntityType<?> entityType, Attribute<?, ?> attribute) { String entityName = entityType.getName(); String attrName = attribute.getName(); if (attribute instanceof PluralAttribute) { return String.format("SELECT COUNT(e) FROM %s e WHERE :targetId MEMBER OF e.%s", entityName, attrName); } else { return String.format("SELECT COUNT(e) FROM %s e WHERE e.%s.id = :targetId", entityName, attrName); } } }package com.kucun.Service; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Service; @Service public class DynamicRepositoryService { private final Map<Class<?>, JpaRepository<?, ?>> repositoryMap = new HashMap<>(); private final Map<String, JpaRepository<?, ?>> repositoryNameMap = new HashMap<>(); public Map<String, JpaRepository<?, ?>> getRepositoryNameMap() { return repositoryNameMap; } public Map<Class<?>, JpaRepository<?, ?>> getRepositoryMap() { return repositoryMap; } public JpaRepository<?,?> getJpaRepository(String e){ // System.out.println("String:"+e+mapToString(repositoryNameMap)); return repositoryNameMap.get(e); } public JpaRepository<?,?> getJpaRepository(Class<?> e){ // System.out.println("Class:"+e+mapToString(repositoryMap)); // System.out.println("Class:"+e); return repositoryMap.get(e); } // 自动注入所有JpaRepository实例 @Autowired public void initRepositories(Map<String, JpaRepository<?, ?>> repositories) { repositories.forEach((name, repo) -> { // 获取代理类实现的接口 Class<?>[] interfaces = repo.getClass().getInterfaces(); for (Class<?> iface : interfaces) { // 扫描接口上的泛型信息 Type[] genericInterfaces = iface.getGenericInterfaces(); for (Type type : genericInterfaces) { if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; // 检查原始类型是否是JpaRepository if (pt.getRawType().equals(JpaRepository.class)) { Type[] args = pt.getActualTypeArguments(); if (args.length >= 2 && args[0] instanceof Class) { Class<?> entityClass = (Class<?>) args[0]; repositoryMap.put(entityClass, repo); String key = entityClass.getSimpleName().toLowerCase(); repositoryNameMap.put(key, repo); // 调试日志 System.out.printf("Mapped %s -> %s [key: %s]%n", entityClass.getName(), repo.getClass().getName(), key); } } } } // 检查接口本身的泛型签名(如果继承的是参数化接口) Type genericSuper = iface.getGenericSuperclass(); if (genericSuper instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericSuper; if (pt.getRawType().equals(JpaRepository.class)) { Type[] args = pt.getActualTypeArguments(); if (args.length >= 2 && args[0] instanceof Class) { Class<?> entityClass = (Class<?>) args[0]; repositoryMap.put(entityClass, repo); String key = entityClass.getSimpleName().toLowerCase(); repositoryNameMap.put(key, repo); // 调试日志 System.out.printf("Mapped %s -> %s [key: %s]%n", entityClass.getName(), repo.getClass().getName(), key); } } } } }); } // 通用保存方法 public <T> T saveEntity(T entity) { JpaRepository<T, ?> repo = (JpaRepository<T, ?>) repositoryMap.get(entity.getClass()); if (repo != null) { return repo.save(entity); } throw new IllegalArgumentException("Repository not found for " + entity.getClass()); } public static String mapToString(Map<?, ?> map) { if (map == null || map.isEmpty()) { return ""; } StringBuilder sb = new StringBuilder(); for (Map.Entry<?, ?> entry : map.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()).append(","); } // 删除最后一个多余的逗号 if (sb.length() > 0) { sb.setLength(sb.length() - 1); } return sb.toString(); } }package com.kucun.data.entity; import java.lang.annotation.Annotation; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.Table; import com.kucun.data.entity.DTO.*; import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonManagedReference; import com.fasterxml.jackson.databind.annotation.JsonSerialize; /** * 板材 * @author Administrator * */ @Entity @Table(name="bancai") @JsonSerialize(using = FullEntitySerializer.class) public class Bancai implements EntityBasis { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "caizhi_id") // private Caizhi caizhi; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "mupi1_id") private Mupi mupi1; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "mupi2_id") private Mupi mupi2; private Double houdu; @OneToOne( cascade = CascadeType.ALL, orphanRemoval = true, // 添加此配置 fetch = FetchType.LAZY ) @JoinColumn(name = "kucun_id", referencedColumnName = "id") private Kucun kucun; public Kucun getKucun() { return kucun; } public void setKucun(Kucun kucun) { this.kucun = kucun; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Caizhi getCaizhi() { return caizhi; } public void setCaizhi(Caizhi caizhi) { this.caizhi = caizhi; } public Mupi getMupi1() { return mupi1; } public void setMupi1(Mupi mupi1) { this.mupi1 = mupi1; } public Mupi getMupi2() { return mupi2; } public void setMupi2(Mupi mupi2) { this.mupi2 = mupi2; } public Double getHoudu() { return houdu; } public void setHoudu(Double houdu) { this.houdu = houdu; } public Bancai(int id, Caizhi caizhi, Mupi mupi1, Mupi mupi2, Double houdu) { super(); this.id = id; this.caizhi = caizhi; this.mupi1 = mupi1; this.mupi2 = mupi2; this.houdu = houdu; } public Bancai() { super(); } } package com.kucun.data.entity; import java.util.List; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.kucun.data.entity.DTO.FullEntitySerializer; /** * 板材材质 * @author Administrator * */ @Entity @Table(name="caizhi", uniqueConstraints = { @UniqueConstraint(columnNames = "name") }) @JsonSerialize(using = FullEntitySerializer.class) public class Caizhi extends SimpleEntity implements EntityBasis{ @OneToMany(mappedBy="caizhi") private List<Bancai> bancais; public Caizhi() { super(); } // 添加反向关联维护方法 public void addBancai(Bancai bancai) { bancais.add(bancai); bancai.setCaizhi(this); } // 添加移除方法 public void removeBancai(Bancai bancai) { bancais.remove(bancai); bancai.setCaizhi(null); } public List<Bancai> getBancais() { return bancais; } public void setBancais(List<Bancai> bancais) { this.bancais = bancais; } } package com.kucun.data.entity; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.hibernate.annotations.Type; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.kucun.data.entity.DTO.FullEntitySerializer; /** * 木皮 * @author Administrator * */ @Entity @Table(name="mupi", uniqueConstraints = { @UniqueConstraint(columnNames = "name") }) @JsonSerialize(using = FullEntitySerializer.class) public class Mupi extends SimpleEntity implements EntityBasis{ /** * 是否有油漆 */ @Column(name="you") @Type(type = "org.hibernate.type.BooleanType") private Boolean you; // 添加 OneToMany 映射 @OneToMany(mappedBy = "mupi1") // 指向 Bancai 中的 mupi1 字段 private List<Bancai> bancaisForMupi1; @OneToMany(mappedBy = "mupi2") // 指向 Bancai 中的 mupi2 字段 private List<Bancai> bancaisForMupi2; public List<Bancai> getBancaisForMupi1() { return bancaisForMupi1; } public void setBancaisForMupi1(List<Bancai> bancaisForMupi1) { this.bancaisForMupi1 = bancaisForMupi1; } public List<Bancai> getBancaisForMupi2() { return bancaisForMupi2; } public void setBancaisForMupi2(List<Bancai> bancaisForMupi2) { this.bancaisForMupi2 = bancaisForMupi2; } public Mupi() { super(); } public Boolean getYou() { return you; } public void setYou(Boolean you) { this.you = you; } } 2025-06-17 13:50:08.559 DEBUG 18340 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : POST "/KuCun2/app/delete/bancai", parameters={} 2025-06-17 13:50:08.561 DEBUG 18340 --- [nio-8080-exec-7] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.kucun.controller.AppController#deleteEntity(String, Map) 2025-06-17 13:50:08.567 DEBUG 18340 --- [nio-8080-exec-7] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [{id=14}] 2025-06-17 13:50:08.585 DEBUG 18340 --- [nio-8080-exec-7] 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 13:50:08.590 DEBUG 18340 --- [nio-8080-exec-7] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json] 2025-06-17 13:50:08.591 DEBUG 18340 --- [nio-8080-exec-7] m.m.a.RequestResponseBodyMethodProcessor : Writing [com.kucun.data.entity.Information@3dee3314] 2025-06-17 13:50:08.591 DEBUG 18340 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : Completed 200 OK 删除失败:null
06-18
package com.kucun.Service; import java.io.Serializable; import java.lang.reflect.*; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; 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.Bancai; import com.kucun.data.entity.Dingdan_chanpin; import com.kucun.data.entity.Dingdan_chanpin_zujian; import com.kucun.data.entity.EntityBasis; import com.kucun.data.entity.Information; import com.kucun.data.entity.Kucun; import com.kucun.dataDo.BancaiRepository; import com.kucun.dataDo.CaizhiRepository; import com.kucun.dataDo.ChanpinRepository; import com.kucun.dataDo.ChanpinZujianRepository; import com.kucun.dataDo.DingdanChanpinRepository; import com.kucun.dataDo.DingdanChanpinZujianRepository; import com.kucun.dataDo.DingdanRepository; import com.kucun.dataDo.KucunRepository; import com.kucun.dataDo.MupiRepository; import com.kucun.dataDo.UserRepository; import com.kucun.dataDo.ZujianRepository; @Service public class AppService { // 注入所有需要的Repository @Autowired private CaizhiRepository caizhiRepository; @Autowired private BancaiRepository bancaiRepository; @Autowired private ChanpinRepository chanpinRepository; @Autowired private DingdanRepository dingdanRepository; @Autowired private MupiRepository mupiRepository; @Autowired private ZujianRepository zujianRepository; @Autowired private KucunRepository kucunRepository; @Autowired private UserRepository userRepository; @Autowired private ChanpinZujianRepository chanpinZujianRepository; @Autowired private DingdanChanpinZujianRepository dingdanChanpinZujianRepository; @Autowired private DingdanChanpinRepository dingdanChanpinRepository; @Autowired private DynamicRepositoryService repositoryService; @Autowired private EntityDependencyService dependencyService; public Information getAllDataWithChildIdse() { Map<String, Object> response = new HashMap<>(); for (String key : repositoryService.getRepositoryNameMap().keySet()) { response.put(key+"s", (repositoryService.getJpaRepository(key).findAll())); } return Information.NewSuccess(response); } public Information getAllDataWithChildIdse(String e) { JpaRepository<?, ?> jp = repositoryService.getJpaRepository(e); System.out.println(jp); return Information.NewSuccess(jp.findAll()); } public Information getAddEntity(Object e) { Class<?> entityClass = e.getClass(); try { // 处理关联字段 handleAssociations(e); @SuppressWarnings("unchecked") JpaRepository<Object, Serializable> jp = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entityClass); Object savedEntity = jp.save(e); if(savedEntity!=null) { if(savedEntity instanceof Bancai) { initializeKucunForBancai((Bancai)savedEntity); } } return Information.NewSuccess(savedEntity); } catch (Exception ex) { return Information.Newfail(500, "创建失败: " + ex.getMessage(), null); } } // 单独封装库存初始化方法 private void initializeKucunForBancai(Bancai bancai) throws Exception { Kucun kucun = new Kucun(null, bancai, 0); // 初始库存为0 try { bancai.setKucun(kucunRepository.save(kucun)); } catch (Exception e) { // TODO: handle exception throw new Exception("initializeKucunForBancai"+e); } } // 处理关联对象(转换为托管实体) private void handleAssociations(Object entity) throws Exception { Class<?> clazz = entity.getClass(); for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); Object value = field.get(entity); if (value == null) continue; // 处理单个关联实体 if (isEntityBasisField(field)) { EntityBasis associatedEntity = (EntityBasis) value; JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(associatedEntity.getClass()); // 获取托管状态的关联实体 Object managedEntity = repo.findById(associatedEntity.getId()) .orElseThrow(() -> new RuntimeException("关联实体不存在")); field.set(entity, managedEntity); } // 处理集合关联 else if (isCollectionField(field)) { Collection<?> collection = (Collection<?>) value; List<Object> managedEntities = new ArrayList<>(); for (Object item : collection) { if (item instanceof EntityBasis) { EntityBasis eb = (EntityBasis) item; JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(eb.getClass()); Object managedEntity = repo.findById(eb.getId()) .orElseThrow(() -> new RuntimeException("关联实体不存在")); managedEntities.add(managedEntity); } } // 更新集合为托管实体 if (!managedEntities.isEmpty()) { field.set(entity, managedEntities); } } } } /** * 更新 * @param e 实体待id * @return */ /** * 更新实体 * @param e 包含ID的实体 * @return 操作结果 */ public Information getupdateEntity(Object e) { if(e == null) { return Information.Newfail(403, "参数为空", null); } Class<?> entityClass = e.getClass(); try { Field idField = entityClass.getDeclaredField("id"); idField.setAccessible(true); Object idValue = idField.get(e); // 修正:应检查id是否为空,而不是不为空 if(idValue == null) { return Information.Newfail(403, "Id为空", null); } // 获取Repository @SuppressWarnings("unchecked") JpaRepository<Object, Serializable> jp = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entityClass); // 从数据库加载现有实体(托管状态) Object existingEntity = jp.findById((Serializable) idValue) .orElseThrow(() -> new RuntimeException("实体不存在")); // 复制属性(排除关联字段) copyNonNullProperties(e, existingEntity); // 保存托管状态的实体 Object updatedEntity = jp.save(existingEntity); return Information.NewSuccess(updatedEntity); } catch (Exception ex) { return Information.Newfail(500, "更新失败: " + ex.getMessage(), null); } } /** * 删除 * @param entity * @return */ public Information getdeleteEntity(EntityBasis entity) { Map<String, Object> response = new HashMap<>(); JpaRepository<Object, Integer> jp= (JpaRepository<Object, Integer>) repositoryService.getJpaRepository(entity.getClass().getSimpleName().toLowerCase()); if(!jp.existsById(entity.getId())) { return Information.NewFail("没有该数据"); } Object d=jp.findById(entity.getId()).orElse(null); for (Class<?> nt : repositoryService.getRepositoryMap().keySet()) { for (Field ent : nt.getDeclaredFields()) { if(ent.getClass().equals(entity.getClass())) { Object o=null; try { o = nt.newInstance(); ent.set(o, d); } catch (InstantiationException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(o); if(getSELECTEntity(o).getData()!=null) { return Information.NewFail("已在其他地方使用了,无法删除"); } } } } try { jp.deleteById(((EntityBasis)entity).getId()); } catch (Exception e) { // TODO: handle exception System.out.println(e.getLocalizedMessage()); } if(jp.existsById(entity.getId())) { System.out.println("删除失败"); return Information.NewFail("删除失败"); } return Information.NewSuccess(response); } // 复制非空属性(忽略关联字段) private void copyNonNullProperties(Object source, Object target) throws IllegalAccessException { Class<?> clazz = source.getClass(); for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); Object value = field.get(source); // 跳过关联字段和特殊字段 if (value != null && !isEntityBasisField(field) && !isCollectionField(field) && !field.getName().equals("id")) { Field targetField; try { targetField = target.getClass().getDeclaredField(field.getName()); targetField.setAccessible(true); targetField.set(target, value); } catch (NoSuchFieldException e) { // 忽略不存在的字段 } } } } // 检查是否为关联实体字段 private boolean isEntityBasisField(Field field) { return EntityBasis.class.isAssignableFrom(field.getType()); } // 检查是否为集合字段 private boolean isCollectionField(Field field) { return Collection.class.isAssignableFrom(field.getType()) || Map.class.isAssignableFrom(field.getType()); } /** * 根据非空属性值动态查询实体 * @param entity 包含查询条件的实体对象(非空属性作为查询条件) * @return 查询结果信息(成功时包含数据列表) */ public <T>Information getSELECTEntity(T entity) { if (entity == null) { return Information.NewFail("查询参数不能为空"); } Class<T> entityClass = (Class<T>) entity.getClass(); try { // 1. 获取非泛型的Repository JpaRepository repository = repositoryService.getJpaRepository(entityClass); // 2. 构建非泛型的Example查询 ExampleMatcher matcher = ExampleMatcher.matching() .withIgnoreNullValues() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING); // 这里直接使用原始类型Example Example<T> example = Example.of(entity);//he type Example is not generic; it cannot be parameterized with arguments <T>the method of(T) is undefined for the type Example // 3. 执行查询 List<?> result = repository.findAll(example); return Information.NewSuccess(result); } catch (ClassCastException e) { return Information.NewFail("Repository类型不匹配: " + e.getMessage()); } catch (DataAccessException e) { return Information.NewFail("数据库访问错误: " + e.getMessage()); } catch (Exception e) { return Information.NewFail("系统错误: " + e.getMessage()); } } private List<Map<String, Object>> convertEntityBasis(List<EntityBasis> entities) { return entities.stream().map(entity -> { Map<String, Object> map = new HashMap<>(); Field[] fields = entity.getClass().getDeclaredFields(); try { // 添加实体自身的基本字段 map.put("id", entity.getId()); // 处理所有字段 for (Field field : fields) { field.setAccessible(true); // 允许访问私有字段 Object fieldValue = field.get(entity); if (fieldValue != null) { String fieldName = field.getName(); // 处理集合类型关联 if (isCollection(field)) { if (!((Collection<?>) fieldValue).isEmpty()) { List<Map<String, Object>> collectionItems = ((Collection<?>) fieldValue) .stream() .filter(item -> item instanceof EntityBasis) .map(item -> { Map<String, Object> itemMap = new HashMap<>(); itemMap.put("id", ((EntityBasis) item).getId()); return itemMap; }) .collect(Collectors.toList()); map.put(fieldName, collectionItems); } } // 处理单个实体关联 else if (implementsInterface(field, EntityBasis.class)) { Map<String, Object> associatedMap = new HashMap<>(); associatedMap.put("id", ((EntityBasis) fieldValue).getId()); map.put(fieldName, associatedMap); } // 处理其他基本类型字段 else if (!isSpecialField(fieldName)) { map.put(fieldName, fieldValue); } } } } catch (IllegalAccessException e) { e.printStackTrace(); } return map; }).collect(Collectors.toList()); } // 判断是否为特殊字段(需要排除的字段) private boolean isSpecialField(String fieldName) { return fieldName.equals("handler") || fieldName.equals("hibernateLazyInitializer"); } /** *-判断属性是否为集合类型 * @param field * @return */ boolean isCollection(Field field) { Class<?> type = field.getType(); // 检查是否为Java内置集合类型 if (Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type) || type.isArray()) { return true; } // 检查是否实现集合相关接口(如Iterable) for (Class<?> interfaceType : type.getInterfaces()) { if (Iterable.class.isAssignableFrom(interfaceType)) { return true; } } return false; } /** * -判断属性是否实现特定接口 * @param field * @param targetInterface * @return */ boolean implementsInterface(Field field, Class<?> targetInterface) { Class<?> type = field.getType(); // 检查类本身是否实现接口 if (targetInterface.isAssignableFrom(type)) { return true; } // 检查实现的接口是否继承目标接口 for (Class<?> interfaceType : type.getInterfaces()) { if (targetInterface.isAssignableFrom(interfaceType)) { return true; } } return false; } private Object convertDingdanChanpins(List<Dingdan_chanpin> findAll) { // TODO Auto-generated method stub return null; } private Object convertDingdanChanpinZujians(List<Dingdan_chanpin_zujian> findAll) { // TODO Auto-generated method stub return null; } } package com.kucun.Service; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Service; @Service public class DynamicRepositoryService { private final Map<Class<?>, JpaRepository<?, ?>> repositoryMap = new HashMap<>(); private final Map<String, JpaRepository<?, ?>> repositoryNameMap = new HashMap<>(); public Map<String, JpaRepository<?, ?>> getRepositoryNameMap() { return repositoryNameMap; } public Map<Class<?>, JpaRepository<?, ?>> getRepositoryMap() { return repositoryMap; } public JpaRepository<?,?> getJpaRepository(String e){ // System.out.println("String:"+e+mapToString(repositoryNameMap)); return repositoryNameMap.get(e); } public JpaRepository<?,?> getJpaRepository(Class<?> e){ // System.out.println("Class:"+e+mapToString(repositoryMap)); // System.out.println("Class:"+e); return repositoryMap.get(e); } // 自动注入所有JpaRepository实例 @Autowired public void initRepositories(Map<String, JpaRepository<?, ?>> repositories) { repositories.forEach((name, repo) -> { // 获取代理类实现的接口 Class<?>[] interfaces = repo.getClass().getInterfaces(); for (Class<?> iface : interfaces) { // 扫描接口上的泛型信息 Type[] genericInterfaces = iface.getGenericInterfaces(); for (Type type : genericInterfaces) { if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; // 检查原始类型是否是JpaRepository if (pt.getRawType().equals(JpaRepository.class)) { Type[] args = pt.getActualTypeArguments(); if (args.length >= 2 && args[0] instanceof Class) { Class<?> entityClass = (Class<?>) args[0]; repositoryMap.put(entityClass, repo); String key = entityClass.getSimpleName().toLowerCase(); repositoryNameMap.put(key, repo); // 调试日志 System.out.printf("Mapped %s -> %s [key: %s]%n", entityClass.getName(), repo.getClass().getName(), key); } } } } // 检查接口本身的泛型签名(如果继承的是参数化接口) Type genericSuper = iface.getGenericSuperclass(); if (genericSuper instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericSuper; if (pt.getRawType().equals(JpaRepository.class)) { Type[] args = pt.getActualTypeArguments(); if (args.length >= 2 && args[0] instanceof Class) { Class<?> entityClass = (Class<?>) args[0]; repositoryMap.put(entityClass, repo); String key = entityClass.getSimpleName().toLowerCase(); repositoryNameMap.put(key, repo); // 调试日志 System.out.printf("Mapped %s -> %s [key: %s]%n", entityClass.getName(), repo.getClass().getName(), key); } } } } }); } // 通用保存方法 public <T> T saveEntity(T entity) { JpaRepository<T, ?> repo = (JpaRepository<T, ?>) repositoryMap.get(entity.getClass()); if (repo != null) { return repo.save(entity); } throw new IllegalArgumentException("Repository not found for " + entity.getClass()); } public static String mapToString(Map<?, ?> map) { if (map == null || map.isEmpty()) { return ""; } StringBuilder sb = new StringBuilder(); for (Map.Entry<?, ?> entry : map.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()).append(","); } // 删除最后一个多余的逗号 if (sb.length() > 0) { sb.setLength(sb.length() - 1); } return sb.toString(); } }package com.kucun.Service; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.metamodel.*; import org.springframework.stereotype.Service; import java.io.Serializable; import java.util.*; import java.util.stream.Collectors; @Service public class EntityDependencyService { @PersistenceContext private EntityManager entityManager; private final Map<Class<?>, Set<Attribute<?, ?>>> associationCache = new HashMap<>(); /** * 检查实体是否被其他实体引用 * @param entityClass 实体类 * @param entityId 实体ID * @return 存在引用返回true */ public boolean hasDependencies(Class<?> entityClass, Serializable entityId) { Metamodel metamodel = entityManager.getMetamodel(); Set<EntityType<?>> entities = metamodel.getEntities(); for (EntityType<?> entityType : entities) { // 跳过自身(避免自引用检查) if (entityType.getJavaType().equals(entityClass)) continue; Set<Attribute<?, ?>> associations = getAssociationAttributes(entityType); for (Attribute<?, ?> attr : associations) { if (attr.getJavaType().isAssignableFrom(entityClass)) { if (isReferenced(entityType, attr, entityId)) { return true; } } } } return false; } /** * 获取实体所有关联属性(带缓存) */ private Set<Attribute<?, ?>> getAssociationAttributes(EntityType<?> entityType) { return associationCache.computeIfAbsent(entityType.getJavaType(), k -> entityType.getAttributes().stream() .filter(Attribute::isAssociation) .collect(Collectors.toSet()) ); } /** * 检查特定关联是否引用目标实体 */ private boolean isReferenced(EntityType<?> entityType, Attribute<?, ?> attribute, Serializable targetId) { String jpql = buildReferenceQuery(entityType, attribute); Long count = (Long) entityManager.createQuery(jpql) .setParameter("targetId", targetId) .getSingleResult(); return count > 0; } /** * 构建引用检查查询 */ private String buildReferenceQuery(EntityType<?> entityType, Attribute<?, ?> attribute) { String entityName = entityType.getName(); String attrName = attribute.getName(); if (attribute instanceof PluralAttribute) { return String.format("SELECT COUNT(e) FROM %s e WHERE :targetId MEMBER OF e.%s", entityName, attrName); } else { return String.format("SELECT COUNT(e) FROM %s e WHERE e.%s.id = :targetId", entityName, attrName); } } }完善删除功能尽量简洁
06-19
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值