Article Directory
1. Reproduce the error
Today, the test lady told me that the home page of the background management system of the test environment reported an error, and sent the following picture:
Since the database of the test environment cannot be modified, the database of the test environment can only be backed up and then copied to my local.
Place the mouse on the backup, right-click to select Restore Backup, and click Start, as shown in the figure below:
[Precautions] Restoring the backup will replace the existing data in the current database, so this should be done with caution.
After backing up to my local, use the local Knife4j
to test the problematic interface, as shown in the following figure:
Sure enough, an exception occurred, ie org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
.
2. Analysis errors
It is catching up ChatGPT
with the fire, and I can use it to return to my question, as shown in the following figure:
But ChatGP
can't answer my question, I can only analyze this exception by myself.
We focus on analyzing Expected one result (or null) to be returned by selectOne(), but found: 2
this sentence and translating it into Chinese is希望返回1个结果(或者null),但返回了2个结果。
Why are two results returned? We continue to analyze.
Locate selectOne()
the place where the method is called, as shown in the following code:
......
// 获取企业用户 id
Wrapper<EnterpriseUser> queryWrapper =new LambdaQueryWrapper<EnterpriseUser>()
.eq(EnterpriseUser::getUserId, tokenProperties.getUserId());
EnterpriseUser enterpriseUser = enterpriseUserService.selectOne(queryWrapper);
......
At the same time, find out mybatis
the printed SQL
statement, as shown in the code:
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2165c177] was not registered for synchronization because synchronization is not active
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@6c5e6da] will not be managed by Spring
==> Preparing: select * from enterprise_user_role r where r.enterprise_user_id = ? and r.role_id in(select id from role where deleted = 0)
==> Parameters: 1(Long)
<== Columns: id, enterprise_user_id, role_id, create_time, update_time, deleted
<== Row: 37, 1, 4, 2023-01-03 16:26:29, 2023-01-03 16:26:28, 0
<== Row: 94, 1, 17, 2023-03-02 10:00:39, 2023-03-02 10:00:37, 0
<== Total: 2
Judging from the above SQL
statement, it is true that a piece of data is returned 2
.
But selectOne()
the method can only return 1
pieces of data, and now it returns 2
pieces of data, so the above error is reported.
At the same time, if multiple pieces of data are queried according to the query conditions, getOne()
the method will also report the above error.
Therefore, we cannot use selectOne()
the or getOne()
method to query multiple pieces of data.
3. Solve the problem
After communicating with the product manager, choose the latest piece of data from the plan given by the product manager.
I use the following two methods to select the latest piece of data.
- Replace
list()
the method withselectOne()
a method, as shown in the following code:
......
// 获取企业用户 id
Wrapper<EnterpriseUser> queryWrapper = new LambdaQueryWrapper<EnterpriseUser>()
.eq(EnterpriseUser::getUserId, tokenProperties.getUserId())
.orderByDesc(EnterpriseUser::getCreateTime);
EnterpriseUser enterpriseUser = null;
List<EnterpriseUser> enterpriseUsers = enterpriseUserService.list(queryWrapper);
if (!enterpriseUsers.isEmpty()) {
enterpriseUser = enterpriseUsers.get(0);
}
......
- Instead of
selectOne()
a method, rewrite a method, as shown in the following code:
EnterpriseUserMapper
selectOneByLimit
new method in class
/**
* 通过用户查询企业用户
*
* @author super先生
* @datetime 2023/3/2:13:34
* @param userId 用户id
* @return 返回企业用户信息
*/
@Select(
"SELECT "
+ " * "
+ "FROM "
+ " enterprise_user_role r "
+ "WHERE "
+ " r.enterprise_user_id = #{userId} "
+ " AND r.role_id IN ( SELECT id FROM role WHERE deleted = 0 ) "
+ "ORDER BY create_time DESC "
+ "LIMIT 1")
EnterpriseUser selectOneByLimit(@Param("userId") Long userId);
EnterpriseUserService
selectOneByLimit
new method of class
/**
* 通过用户查询企业用户
*
* @author super先生
* @datetime 2023/3/2:13:38
* @param userId 用户id
* @return 返回企业用户信息
*/
public EnterpriseUser selectOneByLimit(Long userId) {
return enterpriseUserMapper.selectOneByLimit(userId);
}
- Other service class call
EnterpriseUserService#selectOneByLimit
methods
......
EnterpriseUser enterpriseUser = enterpriseUserService.selectOneByLimit(tokenProperties.getUserId());
......
4. Article Remarks
The above error message is reported: Expected one result (or null) to be returned by selectOne(), but found: 2
.
Generally, you want to query a piece of data, so you use selectOne()
the or getOne()
method. But according to your query conditions, multiple pieces of data are queried.
How to modify it, you can choose the product manager yourself. According to the needs of product managers, to determine the best solution.
If my solution cannot solve your problem, you can leave a message in the comment area, and everyone will make progress together.