org.dbunit.database.AmbiguousTableNameException 终极解决方案
2013-02-22 15:57
701 查看
项目的单元测试用到了dbunit进行数据组装,最近遇到了org.dbunit.database.AmbiguousTableNameException: XXXX数据库表 问题,在网上查找了不少资料,最终还是通过同事的帮助(数据库工程师)一起把问题解决。网上通常的解决方案是对connection增加schema问题即可解决,原因是不同的schema可能会遇到相同的表名,导致抛出错误。 但是这个问题好解决(schema设置为null也可以解决),如下代码: properties.put(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES,
"true");databaseConnection.getConfig().setPropertiesByString(stringProperties) 即可解决。 (由于导入数据库的一个xml里有不同的schema,所有connction不能指定schema)
那问题是什么呢? 由于是测试数据库,最后把"XXXX数据库表"删除掉,问题解决。最后通过数据库工程师分析,通过select * from dba_tables where owner='schmae' and table_name='XXXX数据库表' 可以查询出两条记录,可能是oracle数据库的问题, 从而可推出dbunit源代码里(“罪魁祸首”代码)应该是通过此sql语句进行预加载的,由于有两条重复的表,导致报错。所以数据库工程师将此“垃圾表”清除掉,问题解决。
问题整理:
1.dbunit问题的核心代码如下:
分析:
1.ResultSet resultSet = metadataHandler.getTables(databaseMetaData, schema, tableType);
oracle用户下指定的schema的表可全部查询处理(如果schema为null,则可查询所有权限的表)
2.tableMap.add(tableName,null)
此add方法会先将map里是否有重复的schema.table ,如果有则会抛出
org.dbunit.database.AmbiguousTableNameException: XXXX数据库表 异常。
3.通过select * from dba_tables where owner='schema' and table_name='XXXX数据库表' 分析,有两条记录(一个大写的表,一个是小写的表),删除掉一个解决。
刨根问底:
为什么会出现数据库里有两条表的记录呢? 上网查询后得知,有个笨蛋用户在建表时,通过双引号建的表,比如 create table "XXX数据库表",建好表后估计是发现查不到此表,然后又重新建了一个,最终导致Exception.
"true");databaseConnection.getConfig().setPropertiesByString(stringProperties) 即可解决。 (由于导入数据库的一个xml里有不同的schema,所有connction不能指定schema)
那问题是什么呢? 由于是测试数据库,最后把"XXXX数据库表"删除掉,问题解决。最后通过数据库工程师分析,通过select * from dba_tables where owner='schmae' and table_name='XXXX数据库表' 可以查询出两条记录,可能是oracle数据库的问题, 从而可推出dbunit源代码里(“罪魁祸首”代码)应该是通过此sql语句进行预加载的,由于有两条重复的表,导致报错。所以数据库工程师将此“垃圾表”清除掉,问题解决。
问题整理:
1.dbunit问题的核心代码如下:
private void initialize() throws DataSetException { logger.debug("initialize() - start"); if (_tableMap != null) { return; } try { logger.debug("Initializing the data set from the database..."); Connection jdbcConnection = _connection.getConnection(); DatabaseMetaData databaseMetaData = jdbcConnection.getMetaData(); String schema = _connection.getSchema(); if(SQLHelper.isSybaseDb(jdbcConnection.getMetaData()) && !jdbcConnection.getMetaData().getUserName().equals(schema) ){ logger.warn("For sybase the schema name should be equal to the user name. " + "Otherwise the DatabaseMetaData#getTables() method might not return any columns. " + "See dbunit tracker #1628896 and http://issues.apache.org/jira/browse/TORQUE-40?page=all"); } DatabaseConfig config = _connection.getConfig(); String[] tableType = (String[])config.getProperty(DatabaseConfig.PROPERTY_TABLE_TYPE); IMetadataHandler metadataHandler = (IMetadataHandler) config.getProperty(DatabaseConfig.PROPERTY_METADATA_HANDLER); ResultSet resultSet = metadataHandler.getTables(databaseMetaData, schema, tableType); if(logger.isDebugEnabled()) { logger.debug(SQLHelper.getDatabaseInfo(jdbcConnection.getMetaData())); logger.debug("metadata resultset={}", resultSet); } try { OrderedTableNameMap tableMap = super.createTableNameMap(); while (resultSet.next()) { String schemaName = metadataHandler.getSchema(resultSet); String tableName = resultSet.getString(3); if(_tableFilter != null && !_tableFilter.accept(tableName)) { logger.debug("Skipping table '{}'", tableName); continue; } if(!_oracleRecycleBinTableFilter.accept(tableName)) { logger.debug("Skipping oracle recycle bin table '{}'", tableName); continue; } QualifiedTableName qualifiedTableName = new QualifiedTableName(tableName, schemaName); tableName = qualifiedTableName.getQualifiedNameIfEnabled(config); // Put the table into the table map tableMap.add(tableName, null); } _tableMap = tableMap; } finally { resultSet.close(); } } catch (SQLException e) { throw new DataSetException(e); } }
分析:
1.ResultSet resultSet = metadataHandler.getTables(databaseMetaData, schema, tableType);
oracle用户下指定的schema的表可全部查询处理(如果schema为null,则可查询所有权限的表)
2.tableMap.add(tableName,null)
此add方法会先将map里是否有重复的schema.table ,如果有则会抛出
org.dbunit.database.AmbiguousTableNameException: XXXX数据库表 异常。
3.通过select * from dba_tables where owner='schema' and table_name='XXXX数据库表' 分析,有两条记录(一个大写的表,一个是小写的表),删除掉一个解决。
刨根问底:
为什么会出现数据库里有两条表的记录呢? 上网查询后得知,有个笨蛋用户在建表时,通过双引号建的表,比如 create table "XXX数据库表",建好表后估计是发现查不到此表,然后又重新建了一个,最终导致Exception.
相关文章推荐
- org.dbunit.database.AmbiguousTableNameException异常
- org.dbunit.database.ambiguoustablenameexception
- org.dbunit.database.ambiguoustablenameexception
- [解决方法]org.dbunit.dataset.NoSuchTableException: Did not find table 'tab1' in schema 'null'
- 遭遇org.dbunit.dataset.NoSuchTableException
- org.dbunit.dataset.NoSuchTableException: t_group
- 遭遇org.dbunit.dataset.NoSuchTableException
- 异常org.hibernate.HibernateException: The database returned no natively generated identity解决方案
- org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: ORA-00942: table or view
- org.hibernate.hql.ast.QuerySyntaxException: tablename is not mapped ......
- org.dbunit.dataset.NoSuchColumnException: t_role.ROLE_TYPE - (Non-uppercase input column: role_type
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name解决方案
- java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener错误解决方案
- 让程序在崩溃时体面的退出之终极解决方案(SEH+Dump+Unhandled Exception Filter)(转)
- Bug解决方案:org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 8; 不允许有匹配 "[xX][mM][lL]" 的处理指令目标
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFacto
- (注解方式持久化类报错解决方案-仅供参考)org.hibernate.MappingException: Unknown entity: com.rx.entity.po.User
- org.springframework.dao.InvalidDataAccessApiUsageException:The given object has a null identifi的解决方案
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginAction‘
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFacto