将自己遇到的一些错误总结一下,方便以后复习回顾。同时也希望能帮助一些人
Mybtais错误
1. org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException
1)There is no getter for property named ‘param’ in ‘class java.lang.String’
parameterType=“string”,并判断了 参数是否为空
<select id="xxxxxx" parameterType="string" resultType="int">
SELECT
COUNT(*)
FROM VIEW_USER_INFO T
<where>
<if test="param!=null">
T.CORP_ID like #{param}||'%' OR T.CORP_NAME like '%'||#{param}||'%'
</if>
</where>
</select>
使用<if>
等的标签的时候,默认情况下,mybatis默认使用OGNL寻找String的param属性。
解决方案
- 使用 _parameter 替换参数
- 使用mybatis默认的对象名:value 替换参数
<select id="xxxxxx" parameterType="string" resultType="int">
SELECT
COUNT(*)
FROM VIEW_USER_INFO T
<where>
<if test="value!=null">
T.CORP_ID_CUS like #{param}||'%' OR T.CORP_NAME like '%'||#{param}||'%'
</if>
</where>
</select>
同理,类似的错误 There is no getter for property named 'xxx' in 'class XXXXXX'
,问题一般如下:
- 字段名写错了
- 没有对应的 getter 方法
2) Could not set property ‘xxxx’ of ‘class className’ with value ‘xxxx’
主要原因就是<resultMap id='xx' type="className"><column column="" property="xxx">
property属性名没有写正确,这样就无法在type中指定的类里中找到相应的的settter方法。
2.Cause: java.sql.SQLException: ORA-00911: 无效字符 ; bad SQL grammar []; nested exception is java.sql.SQLException: ORA-00911: 无效字符
; bad SQL grammar []一般是语法错误,检查一下sql是否可以在数据库中正常运行。
但是如果在数据中可以运行的话,检查一下映射文件是否写;
解决方法 : 检查是否在sql语句的末尾有;
,在映射文件中不需要写;
此外,一般情况下一条语句对应一个mapper标签。如果在一个标签中执行多条语句时,也会报该错误。
这与底层的sql驱动程序有关详情
3.在数据库中执行sql有值,使用mabatis取出来后却为null
- 主要的原因就是
实体类属性和数据库 字段无法匹配
,mybatis找不到对应的映射关系,导致为null。 - 如果确定列名称或者别名 和 Java实体中属性名一致。那么检查一下列字段是否使用了下划线_。如果是那么Java实体属性需要修改为不带下划线的方式。即 USER_ID(数据库) -> userId(javabean)
原因可能是开启了下划线和驼峰标记映射
<setting name="mapUnderscoreToCamelCase" value="true"/>
。
4. The content of elements must consist of well-formed character data or markup.
错误的大概意思是 “ 元素内容必须由格式良好的字符数据或者标记组成”,也就是说xml元素中包裹的内容有错误。
网上很多都在说元素本身的错误。比如 < p>aa </p> <122>as</122>
.。有以下依据
XML 元素必须遵循以下命名规则:
- 名称可以含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字符 “xml”(或者 XML、Xml)开始
- 名称不能包含空格
我的问题并不是元素本身的出的问题,而是元素内容(sql 语句)中出现< 和 >
而报出的错误。
-
用转义字符把">“和”<"替换掉。
< < 小于号 > > 大于号
<if test="time!= null "> AND lastLogin <= #{time,jdbcType=DATE}> </if>
-
使用
<![CDATA[ ]]>
符号进行说明,将此类符号不进行解析<if test="time!= null "> AND <![CDATA[ lastLogin <= #{time,jdbcType=DATE} ]]> </if>
5.org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) xxxxxMapper.xxmethod:
一般原因是Mapper interface和xml文件的定义对应不上,需要检查包名,namespace,方法名称等能否对应上。
- 检查配置文件中package名称是否和Mapper接口的全限定类型一致
- 检查映射文件中mapper的namespace属性是否和Mapper接口的全限定类名一致
- 检查Mapper接口中的方法名是否能在映射文件找到对应的id
6. org . apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause : com.mysql.jdbc .MysqlDataTruncation: Data truncation:Incorrect datetime value :’ 10:20:30’
数据库字段和映射文件中配置的字段不匹配。数据库字段‘datetime’,指定的数据类型‘time’。time和datetime 不兼容。
datetime可以兼容timestamp和date类型。
7. org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: The JDBC Type must be specified for output parameter. Parameter: sqlStr
错误原因:调用存储过程时,没有指定输出参数的类型。
<select id="callProcedureHead" statementType="CALLABLE" resultType="map" parameterType="map">
CALL LOOP_QUESTIONNAIRE_HEAD( #{questionnaireId},#{sqlStr,mode=OUT,jdbcType=VARCHAR})
</select>
8.org.springframework.core.NestedIOException: Failed to parse mapping resource: ‘file [xxx.xml]’; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: org.apache.ibatis.builder.BuilderException: Error resolving ParameterMode. Cause: java.lang.IllegalArgumentException: No enum constant org.apache.ibatis.mapping.ParameterMode.in
调用存储过程时,IN,OUT必须大写。
同时mode,javaType,jdbcType 必须小写
9. Mapped Statements collection already contains value for ’ com.example.mapper.TestMapper.selectPerson’
在Mybatis映射文件中 namespace.id
必须唯一。当出现上述问题是,说明 namespace (com.example.mapper.TestMapper)下存在多个 相同的Id(selectPerson)。
- 那么首先检查 映射文件 TestMapper.xml 下是否存在相同的 Id。存在则修改为其他名称即可
- mapper 映射文件可能被加载多次。找出可能加载 mapper.xml 文件的地方
-
spring-boot 配置文件application.properties 或application.yml 自动装配 mybatis
mybatis: mapper-locations:mapper/*
-
加载了 mybatis 配置文件。mybatis-config.xml 配置文件中可以加载 mapper
<mappers> <mapper resource="mybatis/mapper/TestMapper.xml"/> </mappers>
-
自定义配置
mybatis.configuration.mapperLocations=mybatis/mapper/*
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); //配置数据源 factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver(). getResources(mapperLocations)); //加载xml文件
-
10. Parameter ‘__frch_item_0’ not found
在Mybatis 映射文件使用 foreach 元素时可能会抛出该问题。
/* List<User> */
<foreach colleaction="users" item="user" >
#{user.usersId}
</foreach>
我项目中报改错的原因是 属性字段写错了。 实体 User 没有 usersId字段 而是 userId
ORACLE 错误
1. ORA-01013: 用户请求取消当前的操作
这个Oracle报的错误,主要就是请求超时的原因。有可能是当前访问量特别大导致的;也可能是设置的超时间太短;也可能是出现死锁。
我遇到的问题就是死锁,当时在Oracle可视化工具(sql developer)中执行了更新操作但是并没有commit
,所以导致事务一直占用表的写锁。从而导致其他的写操作一直等。 如果是这种原因,commit
提交就可以了
如果是因为请求时间太短导致的问题
#java解决方法
Statement.setQueryTimeout(0);
#修改配置文件
$ORACLE_HOME/network/admin/sqlnet.ora .
#添加或修改成:
sqlnet.expire_time = 0
这将关闭oracle的连接状态检测
Mybatis配置文件 控制请求超时时间
<setting name="defaultStatementTimeout" value="60" />
2. Error querying database. Cause: java.sql.SQLException: ORA-01745: 无效的主机/绑定变量名
因为需要按照指定字段排序所以直接在原来的sql中添加Order by #{orderBy} #{order}
,结果就抛出这个错误。
原因大概如下
- 结果集中的字段含有对应的数据库产品的关键字,
- 在xml文件中的SQL语句中,两个填充变量间没有写逗号。
- 一次性插入大量数据
很明显我的错误的原因时第二个,占位符的方式传递参数是没有逗号将SQL语句中order by #{sortName} #{sortOrder} 改写为<![CDATA[order by ${sortName} ${sortOrder} ]]>
问题就解决了!
我在网上查找资料的时候其实只提供了前两个出错原因。在实际操作的时候因需求需要要插入1000+的数据(大部分数据已经存在其他的数据表里面),此时就报错了。使用的连接池是DruidDataSource,当程序还停留在解析sql语句的时候(预编译sql还有开始赋值),Sql Connection就自动关闭了。当时也查询了很多资料,感觉最好的解释就是,连接池会在一定时间后回收连接。根据指示修改了配置removeAbandonedTimeout
,结果也没有起作用。
后来的解决方案有两种:
- 分块插入,一次插入500条,这样就没有报错了。虽然没有报错但是速度很慢。
- 将数据插入逻辑放在数据库端。这样可能减少mybatis的参数解析工作量,同时减少网络的数据传输量。
INSERT INTO tableName( id,name,sex,....) SELECT #{id},name,sex FROM (子查询语句 | 表名)
。比较推荐这样方式。
3. java.sql.SQLException: ORA-01114: 将块写入文件 201 时出现 IO 错误 (块 # 1015305)
ORA-27069: skgfdisp: 尝试在文件范围外执行 I/O
OSD-04026: 传递的参数无效。 (OS 1015311)
ORA-01114: 将块写入文件 201 时出现 IO 错误 (块 # 1015305)
ORA-27069: skgfdisp: 尝试在文件范围外执行 I/O
OSD-04026: 传递的参数无效。 (OS 1015311)
场景 : 导出大量历史数据到csv文件中的时候,抛出该错误。
错误原因: 数据库临时表空间满了或者坏掉了
解决方案:
查询临时表空间的大小
select creation_time,name, bytes/1024/1024 as “大小(M)” from v$tempfile order by bytes;
可能就是因为临时空间太小并且不能扩容的原因。
解决办法:
1、查询该用户下的默认临时表空间
select * from database_properties where property_name=‘DEFAULT_TEMP_TABLESPACE’;
2、创建新的临时表空间
create temporary tablespace temp01 tempfile ‘xxxxxxx.DBF’ size 1000M autoextend on;
3、修改默认表空间
alter database default temporary tablespace temp01;
参考博客ORA-01114错误原因及解决方法(临时表空间坏掉、或者满了)
4. ORA-00018 Maximum number of sessions exceeded超出最大会话数
Oracel默认Process的值为150,导致实际的Session值会超过Oracle的设置值(Session的数量是Process*1.1+5),所以会出错。
5. ORA-01791:not a SELECTed expression
select distinct name from DM.USER_BASE order by created_time desc;
类如上面的sql语句就会报该错误,因为 distinct 和order by一起使用的时候,order by中必须是常量或者select列表中出现的表达式。
有点像group by
select distinct name,created_time from DM.USER_BASE order by created_time desc;
ORA-01461:仅能绑定要插入 LONG 列的 LONG 值
错误场景:日志插入错误信息时,没有限定长度,结果e.toString()异常信息特别多。就报的这个错误。
原因: Oracle 中 如果字节类型大于4000个字节时就会被转成Long型。
- 可以限定异常信息长度
- 修改数据类型