code

Oracle + dbunit에서 AmbidgeTableName 예외가 발생함

starcafe 2023. 9. 25. 22:53
반응형

Oracle + dbunit에서 AmbidgeTableName 예외가 발생함

데이터베이스 백업을 만들기 위해 dbunit을 사용하고 있으며, 데이터베이스 백업은 가져오기와 내보내기가 가능합니다.애플리케이션은 여러 데이터베이스 엔진을 사용할 수 있습니다.MySQL, PostgreSQL, SQL 서버, H2 및 Oracle.

다음 코드를 사용하면 위의 모든 것이 정상적으로 작동합니다.

            // Connect to the database 
        conn =BackupManager.getInstance().getConnection();
        IDatabaseConnection connection = new DatabaseConnection(conn);
        InputSource xmlSource = new InputSource(new FileInputStream(new File(nameXML)));
        FlatXmlProducer flatXmlProducer = new FlatXmlProducer(xmlSource);
        flatXmlProducer.setColumnSensing(true);

        DatabaseOperation.CLEAN_INSERT.execute(connection,new FlatXmlDataSet(flatXmlProducer));  

그러나 Oracle의 경우에는 다음과 같은 예외가 있습니다.

!ENTRY es.giro.girlabel.backup 1 0 2012-04-11 11:51:40.542
!MESSAGE Start import backup
org.dbunit.database.AmbiguousTableNameException: AQ$_SCHEDULES
    at org.dbunit.dataset.OrderedTableNameMap.add(OrderedTableNameMap.java:198)
    at org.dbunit.database.DatabaseDataSet.initialize(DatabaseDataSet.java:231)
    at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:281)
    at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:109)
    at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
    at es.giro.girlabel.backup.ImportBackup.createData(ImportBackup.java:39)
    at es.giro.girlabel.backup.handlers.Import.execute(Import.java:45)

문서에서:

public class AmbiguousTableNameException extends DataSetException

이 예외는 다음과 같이 처리됩니다.IDataSet동일한 이름을 가진 여러 테이블에 액세스할 수 있는 경우.이 문제는 일반적으로 데이터베이스 연결이 동일한 테이블 이름을 포함하는 여러 스키마에 액세스할 때 발생합니다.

가능한 해결책:

1) 하나의 데이터베이스 스키마에만 액세스할 수 있는 데이터베이스 연결 자격 증명을 사용합니다.

2) 스키마 이름 지정DatabaseConnection아니면DatabaseDataSourceConnection시공자

3) 적합한 테이블 이름 지원을 사용 가능으로 설정합니다(사용 방법 설명서 참조).

Spring DBIT을 사용하는 사용자.저는 이 아주 성가신 문제 때문에 애를 먹었습니다.에 대한 구성을 추가하여 문제를 해결했습니다.com.github.springtestdbunit.bean.DatabaseConfigBean그리고.com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean.

이것은 Spring DBUnit의 전체 스프링 컨텍스트입니다.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@localhost:1521/XE" />
        <property name="username" value="xxxx" />
        <property name="password" value="xxxx" />
    </bean>


    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
        <property name="annotatedClasses">
            <list>
                <value>xxx.example.domain.Person</value>
            </list>
        </property>
    </bean>

    <bean id="dbUnitDatabaseConfig" class="com.github.springtestdbunit.bean.DatabaseConfigBean">
        <property name="skipOracleRecyclebinTables" value="true" />
        <property name="qualifiedTableNames" value="true" />
        <!-- <property name="caseSensitiveTableNames" value="true"/> -->
    </bean>
    <bean id="dbUnitDatabaseConnection"
        class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="databaseConfig" ref="dbUnitDatabaseConfig" />
        <property name="schema" value="<your_schema_name>"/>
    </bean>

데이터베이스 스키마를 설정하면 다음과 같이 수정할 수 있습니다.

@Bean
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection(final DataSource dataSource){
    final DatabaseDataSourceConnectionFactoryBean connectionFactory = new DatabaseDataSourceConnectionFactoryBean();
    connectionFactory.setDataSource(dataSource);
    connectionFactory.setSchema(DB_SCHEMA);
    return connectionFactory;
}

오라클 DB에 대해 D units를 실행하는 동안 동일한 AmbidgeTableNameException이 발생했습니다.잘 작동하다가 어느 날부터 오류를 던지기 시작했습니다.

근본 원인: 저장 프로시저 호출 중 실수로 소문자로 수정되었습니다.상부 케이스로 변경하면 작동하는 것처럼 보입니다.

쉐마 이름을 아이디 데이터베이스로 설정하여 해결할 수 있었습니다.iDatabase와 같은 테스터테스터.sSchema("SCHEMANAME INCAPS")

또한 동일한 테이블 이름을 가진 많은 스키마에만 접속하지 않도록 해주세요.

DBUnit가 실행되기 전에 최대 절전 모드에서 데이터를 가져올 때 문제가 발생할 수 있습니다.사용 중인 데이터베이스에 따르면 테이블과 열 이름의 케이싱이 중요할 수 있습니다.

예를 들어 HSQL에서는 데이터베이스 이름을 대문자로 선언해야 합니다.Hibernate의 import.sql을 통해 데이터를 가져올 경우 테이블 이름도 대문자여야 합니다. 그렇지 않으면 다음과 같은 문제가 발생합니다.

  • 최대 절전 모드에서는 소문자로 테이블이 생성됩니다.
  • DBUnit는 소문자로 DB에서 테이블 이름을 읽습니다.
  • DBUit가 대문자 테이블 이름을 사용하여 데이터셋 가져오기를 시도합니다.
  • 모호한 이름 예외로 결국 엉망이 됩니다.

또한 이전 실행 중에 여러 개의 테이블이 생성되었는지(상/하부 모두) 확인해야 합니다. 이 경우에도 테이블을 정리해야 합니다.

Oracle을 사용한 저는 ALL 또는 DBA 대신 몇 가지 권한을 가진 단순한 생성 스키마를 사용했습니다.Dbunit이 다른 스키마의 테이블과 충돌을 중지했습니다.

GRANT CREATE SESSION, CONNECT, RECOURCE TO testdb IDENTIFIED BY testdb;

언급URL : https://stackoverflow.com/questions/10103629/oracle-dbunit-gets-ambiguoustablenameexception

반응형