我有一个插入句子,该句子出现了重复键,它应该作为DuplicateKeyException抛出,但是我却有一个MySQLIntegrityConstraintViolationException。 为什么Spring没有将其包装为DuplicateKeyException?
高度赞赏。讨论欢迎。
代码和异常堆栈在下面。
异常堆栈:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '2750633-163072083-袋-0' for key 'uk_unit_name'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:932)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
at com.dianping.zebra.single.jdbc.SinglePreparedStatement$2.doAction(SinglePreparedStatement.java:83)
at com.dianping.zebra.single.jdbc.SinglePreparedStatement$2.doAction(SinglePreparedStatement.java:80)
at com.dianping.zebra.single.jdbc.SingleStatement.executeWithFilterOrigin(SingleStatement.java:228)
at com.dianping.zebra.single.jdbc.SingleStatement.access$000(SingleStatement.java:37)
at com.dianping.zebra.single.jdbc.SingleStatement$8.executeSingleStatement(SingleStatement.java:215)
at com.dianping.zebra.filter.DefaultJdbcFilter.executeSingleStatement(DefaultJdbcFilter.java:59)
at com.dianping.zebra.single.jdbc.SingleStatement$8.executeSingleStatement(SingleStatement.java:212)
at com.dianping.zebra.filter.DefaultJdbcFilter.executeSingleStatement(DefaultJdbcFilter.java:59)
at com.dianping.zebra.single.jdbc.SingleStatement$8.executeSingleStatement(SingleStatement.java:212)
at com.dianping.zebra.filter.DefaultJdbcFilter.executeSingleStatement(DefaultJdbcFilter.java:59)
at com.dianping.zebra.single.jdbc.SingleStatement$8.executeSingleStatement(SingleStatement.java:212)
at com.dianping.zebra.monitor.filter.CatFilter.executeSingleStatement(CatFilter.java:153)
at com.dianping.zebra.single.jdbc.SingleStatement$8.executeSingleStatement(SingleStatement.java:212)
at com.dianping.zebra.single.jdbc.SingleStatement.executeWithFilter(SingleStatement.java:220)
at com.dianping.zebra.single.jdbc.SinglePreparedStatement.executeUpdate(SinglePreparedStatement.java:80)
at com.dianping.zebra.single.jdbc.SinglePreparedStatement.execute(SinglePreparedStatement.java:62)
at com.dianping.zebra.group.jdbc.GroupPreparedStatement.executeUpdateOnConnection(GroupPreparedStatement.java:172)
at com.dianping.zebra.group.jdbc.GroupPreparedStatement.executeUpdate(GroupPreparedStatement.java:159)
at com.dianping.zebra.group.jdbc.GroupPreparedStatement.execute(GroupPreparedStatement.java:98)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:44)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:69)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:105)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:71)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:152)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:141)
at sun.reflect.GeneratedMethodAccessor130.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:408)
at com.sun.proxy.$Proxy46.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:254)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:51)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
at com.sun.proxy.$Proxy58.insertSelective(Unknown Source)
at sun.reflect.GeneratedMethodAccessor314.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.dianping.zebra.dao.AsyncMapperProxy.invoke(AsyncMapperProxy.java:67)
at com.sun.proxy.$Proxy58.insertSelective(Unknown Source)
at com.hh6plus.repository.impl.UnitRepositoryImpl.create(UnitRepositoryImpl.java:53)
呼叫者代码:
@Slf4j
@Repository
public class UnitRepositoryImpl implements UnitRepository {
@Autowired
private UnitMapper unitMapper;
@Override
public void create(Unit unit, boolean checkNameDuplicate) {
UnitPO po = UnitPoConverter.convertToPo(unit);
try {
/***** exception thrown below *****/
unitMapper.insertSelective(po);
fillUnitIdWithId(po.getTenantId(), po.getPoiId(), po.getId(), po);
} catch (DuplicateKeyException e) {
/***** code expected to be processed, but not happened. *****/
if (checkNameDuplicate) {
throw e;
}
log.warn("duplicate.unit:{}.", unit, e);
List<Unit> existsUnits = this.findByName(unit.getTenantId(), unit.getPoiId(), unit.getName());
if (CollectionUtils.isNotEmpty(existsUnits)) {
Unit existsUnit = existsUnits.get(0);
BeanUtils.copyProperties(existsUnit, unit);
}
}
}
}
被叫方代码:
java代码:
public interface UnitMapper {
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table unit
*
* @mbggenerated Thu Jul 19 18:07:32 CST 2018
*/
int insert(UnitPO record);
}
mybatis xml:
<insert id="insertSelective" parameterType="com.hh6plus.dao.model.UnitPO">
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Jul 19 18:07:32 CST 2018.
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
SELECT LAST_INSERT_ID()
</selectKey>
insert into unit
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="tenantId != null">
tenant_id,
</if>
<if test="poiId != null">
poi_id,
</if>
<if test="name != null">
name,
</if>
<if test="rank != null">
rank,
</if>
<if test="operator != null">
operator,
</if>
<if test="deleted != null">
deleted,
</if>
<if test="createdTime != null">
created_time,
</if>
<if test="modifiedTime != null">
modified_time,
</if>
<if test="unitId != null">
unit_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="tenantId != null">
#{tenantId,jdbcType=INTEGER},
</if>
<if test="poiId != null">
#{poiId,jdbcType=INTEGER},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="rank != null">
#{rank,jdbcType=BIGINT},
</if>
<if test="operator != null">
#{operator,jdbcType=INTEGER},
</if>
<if test="deleted != null">
#{deleted,jdbcType=BIGINT},
</if>
<if test="createdTime != null">
#{createdTime,jdbcType=TIMESTAMP},
</if>
<if test="modifiedTime != null">
#{modifiedTime,jdbcType=TIMESTAMP},
</if>
<if test="unitId != null">
#{unitId,jdbcType=BIGINT},
</if>
</trim>
</insert>
答案 0 :(得分:0)
问题解决了。 实际上,springframework将SQLException包装到DuplicateKeyException中并被捕获。 我说没有被捕获的原因是,我被公司中的一个日志组件误导了,该组件自动记录SQLException,而与代码中的catchensen无关。 抱歉,我的信息不正确。