1.问题
Java代码:
@Component @DS("greenplum") public class GreenPlumComponent { @Resource private CommonMapper commonMapper; private AtomicInteger nextVal; @PostConstruct public int querySeqNextVal() { if (nextVal == null) { // seqName 是通过配置文件传过来的这里为了简洁删除了配置文件代码 this.nextVal = new AtomicInteger(commonMapper.querySeqNextValBySeqName("seqName")); } return nextVal.getAndIncrement(); } }
Mapper文件内的SQL:
<select id="querySeqNextValBySeqName" resultType="java.lang.Integer"> SELECT nextval( #{seqName} ) </select>
运行报错:
Cause: java.sql.SQLSyntaxErrorException: FUNCTION mysql.nextval does not exist; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: FUNCTION xa-mysql.nextval does not exist
异常的原因是: 本应该查询greenplum
查询的却是mysql
,也就是@DS("greenplum")
未生效。
2.解决
Java代码去掉 @PostConstruct
:
@Component @DS("greenplum") public class GreenPlumComponent { @Resource private CommonMapper commonMapper; private AtomicInteger nextVal; public int querySeqNextVal() { if (nextVal == null) { // seqName 是通过配置文件传过来的这里为了简洁删除了配置文件代码 this.nextVal = new AtomicInteger(commonMapper.querySeqNextValBySeqName("seqName")); } return nextVal.getAndIncrement(); } }
调用:
@Autowired private GreenPlumComponent greenPlumComponent; private List<Map> dealData() { // 使用 int nextVal = greenPlumComponent.querySeqNextVal(); }
3.分析
可能的问题:
- 由于 @Component 容器实例化后会调用 @PostConstruct 注解的方法,此时方法的调用并非实例对象调用。
- @DS 注解利用的是 AOP 非实例对象调用无法触发。
求证后会更新内容,当前仅作记录。