多根路径扫描下@Entity未被管理致Repository Bean创建失败解决
@Entity类被提示为非托管类型的原因与解决方法
问题背景
存在com.domain.app和net.domain.app两个包,标注@SpringBootApplication的MyApplication类位于com.domain.app包内,当前在net.domain.app包开发新功能。@Service组件可正常运行,添加@Repository后通过配置@EnableJpaRepositories(basePackages = {"com.domain.app", "net.domain.app"})解决了仓库相关错误,但net.domain.app包下的@Entity类被提示为非托管类型。
报错信息
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'repo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository' defined in net.conselldemallorca.sirh.business.security.boundary.UserRepository defined in @EnableJpaRepositories declared on MyApplication: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class net.domain.app.security.entity.User ... Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository' defined in net.domain.app.security.boundary.UserRepository defined in @EnableJpaRepositories declared on MyApplication: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class net.domain.app.security.entity.User ... Caused by: java.lang.IllegalArgumentException: Not a managed type: class net.domain.app.security.entity.User
相关代码示例
MyApplication.java
package com.domain.app; @SpringBootApplication @ComponentScan(basePackages = {"com.domain.app", "net.domain.app"}) @EnableJpaRepositories(basePackages = {"com.domain.app", "net.domain.app"}) public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
UserRepository.java
package net.domain.app.security.boundary; @Repository public interface UserRepository extends JpaRepository<User, Long> { ... }
UserService.java
package net.domain.app.security.boundary; @Service @Transactional(rollbackFor = Throwable.class) public class UserService implements UserServiceable { @Autowired UserRepository repo; ... }
User.java
package net.domain.app.security.entity; import javax.persistence.*; import javax.validation.constraints.NotNull; import java.io.Serializable; import java.util.Objects; ... @Entity @Table(name = "USER") public class User implements Serializable { ... }
原因分析
Spring Data JPA默认只扫描@SpringBootApplication所在包(com.domain.app)及其子包下的@Entity类。新增的User实体在net.domain.app包下,不在默认扫描范围内,因此被判定为非托管类型。注意@EnableJpaRepositories仅负责Repository接口的扫描,不影响实体类的扫描范围。
解决方法
方法一:添加@EntityScan指定实体扫描包
在MyApplication类上添加@EntityScan注解,明确指定要扫描的实体所在包:
package com.domain.app; @SpringBootApplication @ComponentScan(basePackages = {"com.domain.app", "net.domain.app"}) @EnableJpaRepositories(basePackages = {"com.domain.app", "net.domain.app"}) @EntityScan(basePackages = {"com.domain.app", "net.domain.app"}) // 新增该行 public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
方法二:精准指定实体子包
如果两个包下的实体都集中在特定子包(比如.entity或.security.entity),可以更精准地配置,减少扫描范围:
@EntityScan(basePackages = {"com.domain.app.entity", "net.domain.app.security.entity"})
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

