2020/02/28更新 - 简化版
原文废话太多,已删,长话短说:
问题描述:SpringBootApplication启动失败,报UnsatisfiedDependencyException异常,无法注入相关repository对象()
repository对象注入失败,请注意以下几点:
一、自定义repository类继承JapRepository时务必要指定泛型<EntityClass, EntityPrimaryKeyType>,例如:
public interface UserRepository extends JpaRepository<User,Integer>() {}
其中User是数据库的实体类,Integer是实体类中对应主键的成员变量的数据类型
二、确定Bean类定义正确,加上了必要的注解
请确保你在Bean类的定义里加了@Entity、@Table、@Id、@Column这些注解(javax.persistance包),例如:
@Entity
@Table(name="user")
class User {
@Id
private Integer uid;
@Column
private String username;
@Column
private String password;
}
三、确定你的Bean类能被Spring容器扫描到
SpringBootApplication的启动类默认扫描范围是与自身同目录及以下,如果你的Bean类不在此范围内(比如分布式、微服务开发的场景中Bean类一般都写在另一个模块里),请指定扫描范围,例如:
//模块包名有共同前缀的情况下:
@SpringBootApplication(scanBasePackages = {"cn.shadl"})
//模块包名没有共同前缀的情况下:
@SpringBootApplication(scanBasePackages = {"com.example.A(这个服务自己所在的包)" , "cn.exp2.B(另一个服务里的包)"})
四、repository类没必要加@Repository注解
SSM过来的人可能会踩到这个坑,应用层加@Controller,服务层加@Service,持久层加@Repository
需知@Controller,@Service,@Repository三个其实都是@Component的衍生子类,作用是将类加入Spring容器。
但使用SpringDataJpa请勿给你的持久层接口加@Repository或者其他注入容器的注解,因为当你继承JpaRepository的时候你的接口就已经在Spring容器里注册了,强行加就会被识别成有两个重名的bean,报NoUniqueBeanDefinitionException。
//错误示范:
@Repository
public interface ItemRepository extends JpaRepository<Item,Long>() {}
//结果:
报NoUniqueBeanDefinitionException
以上就是主要的注意事项,希望能帮到路过的debug网友。
2020/01/22 原文已删(流水账,请看上面精简版以避免浪费时间)
2020/02/24更新
新增一个踩坑案例!
依然是在application类启动时报错:创建名为“userRepository”的Bean时失败,调用初始化方法失败
原因:userRepository接口,自定义方法名的错误
现有:
- List<User> findByUserName(String username);
- List<User> findByUserNameAndPassword(String username, String password);
上面的“UserName”一时大意输入了大写的“N”,鉴于表中对应字段及其domain包实体类中的成员变量为username,而java对大小写敏感,所以找不到“userName”的对应映射关系。
解决方法:更正大小写问题
- List<User> findByUsername(String username);
- List<User> findByUsernameAndPassword(String username, String password);