Spring集成MongoDB查询时抛出org.springframework.data.mapping.MappingException
Spring集成MongoDB查询时MappingException异常分析与解决
我来帮你梳理这个问题的原因和解决办法,之前我也碰到过类似的Spring Data映射问题,咱们一步步来看:
首先先还原你的代码场景,DAO层的实现如下:
@Repository("usersDao") public class UserDaoImpl implements UserDao { @Autowired MongoTemplate mongoTemplate; @Override public void saveUser(User user) { mongoTemplate.save(user); } @Override public User findUserByUserName(String userName) { return mongoTemplate.findOne( new Query(Criteria.where("_id").is(userName)), User.class); } }
执行查询时抛出的核心异常是:
org.springframework.data.mapping.MappingException: Parameter org.springframework.data.mapping.PreferredConstructor$Parameter@d1c79025 does not have a name! at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:61) ~[spring-data-commons-2.0.6.RELEASE.jar:2.0.6.RELEASE] // 后续堆栈信息省略
异常原因分析
这个异常的本质是Spring Data无法获取到User实体类构造函数的参数名称,导致没法把MongoDB返回的文档字段映射到实体对象上。通常触发这个问题的场景有三种:
User类只提供了带参数的构造函数,没有无参构造函数;- 带参数的构造函数没有通过注解绑定字段名,且Java编译时没有保留参数元数据;
- 编译项目时未开启
-parameters参数,导致Spring Data无法通过反射获取构造参数的名称。
解决方法
方法1:给User类添加无参构造函数
Spring Data默认优先使用无参构造函数实例化实体对象,这是最简单直接的解决方案:
public class User { private String userName; // 对应MongoDB的_id字段 private String password; // 其他业务字段 // 添加无参构造函数 public User() {} // 你的带参构造(如果需要保留的话) public User(String userName, String password) { this.userName = userName; this.password = password; } // getter和setter方法 }
方法2:给带参构造函数添加@ConstructorProperties注解
如果你的User类需要做不可变对象(不想提供无参构造和setter),可以用@ConstructorProperties注解明确绑定构造参数和实体字段的对应关系:
import java.beans.ConstructorProperties; public class User { private final String userName; private final String password; @ConstructorProperties({"userName", "password"}) public User(String userName, String password) { this.userName = userName; this.password = password; } // 只提供getter方法即可 public String getUserName() { return userName; } public String getPassword() { return password; } }
方法3:开启Java编译的-parameters参数
如果不想修改实体类代码,可以通过配置编译参数,让Java编译器保留构造函数和方法的参数名称元数据:
Maven项目配置(pom.xml)
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <!-- 替换为你的JDK版本 --> <target>1.8</target> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin> </plugins> </build>
Gradle项目配置(build.gradle)
compileJava { options.compilerArgs << '-parameters' }
开启该参数后,Spring Data就能通过反射自动识别构造参数的名称,完成字段映射。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

