9

ここで dbunit に関する議論があったことは知っています。それらのほとんどを読みましたが、問題の解決策が見つからないようです。

休止状態と春を設定しました。私はTDDを行っているので、コードを書く前に適切なDAOテストフレームワークを接続する必要がありました. Dbunit が頭に浮かび、それをセットアップする必要がありました。ここにma testdataset.xmlがあります

    <?xml version='1.0' encoding='UTF-8'?>
    <dataset>
        <table name="status">
            <column>statusId</column>
            <column>status</column>
            <row>
                <value>0</value>
                <value>Available</value>
            </row>
        </table>
        <table name="user">
            <column>userId</column>
            <column>firstName</column>
            <column>lastName</column>
            <column>username</column>
            <column>password</column>
            <column>email</column>
            <row>
                <value>0</value>
                <value>system</value>
                <value>admin</value>
                <value>admin</value>
                <value>admin</value>
                <value>admin@ccbs.com</value>
            </row>
        </table>
        <table name="reservation">
            <column>reservationId</column>
            <column>userId</column>
            <column>reservationDate</column>
            <column>startDate</column>
            <column>endDate</column>
            <column>statusId</column>
            <row>
                <value>0</value>
                <value>0</value>
                <value>2011-02-20 12:46:00.0</value>
                <value>2011-03-01 12:00:00.0</value>
                <value>2011-04-01 12:00:00.0</value>
                <value>0</value>
            </row>
        </table>
    </dataset>

データセットをロードする基本クラスを使用していくつかのコードを接続しようとするまで、すべてがうまくいくようです。これが私のコードです:

@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:test-applicationContext.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class BaseContextSensitiveTest {

    @BeforeClass
public static void setUpDatabase() throws Exception {
    URL file = getInitalDatasetURL();
    testDataset = createDataset(file);
}

   @Before
public void init() throws Exception {
    log.info("Initializing Data Set");
    connection = createDBUnitConnection();

    DatabaseOperation.CLEAN_INSERT.execute(connection, testDataset);
}

private static URL getInitalDatasetURL() throws FileNotFoundException {
    URL file = ClassLoader.getSystemResource(TEST_DATASET_LOCATION);
    if (file == null) {
        throw new FileNotFoundException("Unable to find '"
                + TEST_DATASET_LOCATION + "' in the classpath");
    }
    return file;
}

private static IDataSet createDataset(URL file) throws IOException,
        DataSetException {

    return new XmlDataSet(file.openStream());
}

private IDatabaseConnection createDBUnitConnection()
        throws DatabaseUnitException, SQLException {

    Connection connection = getConnection();
    IDatabaseConnection dbUnitConn = new DatabaseConnection(connection);

    // use the hsql datatypefactory so that boolean properties work
    // correctly
    DatabaseConfig config = dbUnitConn.getConfig();
    config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
            new HsqldbDataTypeFactory());

    return dbUnitConn;
}

ヒットするとすぐにDatabaseOperation.CLEAN_INSERT.execute(connection, testDataset);、次の例外がスローされます。

org.dbunit.dataset.NoSuchTableException: Did not find table 'USER' in schema 'null'
at org.dbunit.database.DatabaseTableMetaData.<init>(DatabaseTableMetaData.java:142)
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:290)
at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:109)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
at com.cottage.test.BaseContextSensitiveTest.init(BaseContextSensitiveTest.java:64)

すべての休止状態のマッピング ファイルが配置されており、データベースは既にデータなしでセットアップされています。面白いこと (または、見方によっては面倒なこと) は、データセット内のテーブルの順序を変更すると、missingtableexception が別のテーブルについて不平を言うことです... ユーザー、予約、またはステータスのいずれかです。

私が間違っているかもしれないことについて何か提案はありますか?

4

7 に答える 7

13

私もこれと同じエラーに遭遇しましたが、上記の受け入れられた修正では問題が解決しませんでした。しかし、私は解決策を見つけることができました。

私のセットアップは、DBUnit(2.4)、JPA プロバイダーとしての EclipseLink(2.1)、およびバックエンド データベースとしての Postgres で構成されていました。また、私のシナリオでは、テストを実行するたびにテーブルを削除して再作成していませんでした。私のテストデータはすでに存在していました。私が知っている悪い習慣ですが、それはテスト/プロトタイピングのシナリオのようなものでした. 以下のコードは、私の問題を解決するために使用される DBUnit 構成を示しています。

54    // ctx represents a spring context
55    DataSource ds = (DataSource)ctx.getBean("myDatasourceBean");
56    Connection conn = DataSourceUtils.getConnection(ds);
57    IDatabaseConnection dbUnitConn = new DatabaseConnection(conn, "public");
58    DatabaseConfig dbCfg = dbUnitConn.getConfig();
59    dbCfg.setFeature(DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES, Boolean.TRUE);
60    IDataSet dataSet = new FlatXmlDataSet(ClassLoader.getSYstemResourceAsStream("mydbunitdata.xml"));
61    DatabaseOperation.REFRESH.execute(dbUnitConn, dataSet);

上記のコードの 2 つのことが問題を解決しました。最初に、DBUnit が使用するスキーマを定義する必要がありました。これは、上記の 57 行目で行われます。新しい DatabaseConnection が設定されている場合、スキーマ ("public") が null でない場合は渡す必要があります。

次に、DBUnit でデータベース テーブル名の大文字と小文字を区別する必要がありました。私の DBUnit xml ファイル ("mydbunitdata.xml") では、テーブル名はデータベースにあるようにすべて小文字です。ただし、大文字と小文字を区別するテーブル名を使用するよう DBUnit に指示しない場合、Postgres が好まない大文字のテーブル名が検索されます。したがって、59行目で行われるDBUnitで大文字と小文字を区別する機能を設定する必要がありました.

于 2011-09-23T13:57:48.730 に答える
10

dataset.xml ファイルの最初の行を削除します

<!DOCTYPE dataset>

そしてこれに置き換えます

<?xml version='1.0' encoding='UTF-8'?>

そうしないと、DBUnit は DTD ファイルから db テーブル スキーマを読み込もうとし、DTD が指定されていない場合、どのテーブルとも一致しません。プレーンな xml ヘッダーを使用すると、DBUnit はこの DTD をスキップします。これは、表示されているエラーをスローしているテーブル チェックです。

また、Grzegorz が行ったことを実行し、Hibernate にテーブルの create-drop を実行させる必要があります。

<property name="hibernate.hbm2ddl.auto" value="create-drop"/>

また

configuration.setProperty(Environment.HBM2DDL_AUTO, "create-drop");

于 2011-05-06T17:43:55.140 に答える
8

DBUnit は、意図したデータベース スキーマを作成するためのデータセット xml からの情報が限られているため、データベース テーブルを作成しません。

hibernate と組み合わせて使用​​する場合、すべての pojo (インメモリ テスト データベース テーブルにマップしようとしているもの) に対して適切な hbm マッピング ファイルが必要になり、最終的にテストで使用されます。マッピング ファイルがないと、org.dbunit.dataset.NoSuchTableException: Did not find table 'xxx' in schema 'yyy'.

また、有効な hibernate.cfg.xml が必要であり、すべての hibernate マッピング ファイルで正しく構成されています。

プロパティ ファイルでこのプロパティhibernate.hbm2ddl.auto=create-dropを設定することにより、データベースの作成を休止状態に委任できます。

エラー メッセージは少し誤解を招きます。おそらく、欠落している hibernate マッピング ファイルに関する詳細情報が含まれているはずですが、これは DBunit wiki での議論です。

于 2011-02-21T20:32:23.930 に答える
3

データベースにデータベース テーブルを作成しましたか?

dbunit意図したデータベース構造がわからないため、あなたに代わってそれを行いません。ただし、Hibernat に実行を依頼することはできます。hbm2ddlフラグを使用します。例:

 <property name="hibernate.hbm2ddl.auto" value="create-drop"/>

フラグの主なドキュメントは見つかりませんでしたが、検索すると多くの結果が得られます。http://docs.jboss.org/ejb3/docs/reference/build/reference/en/html/entityconfig.html

于 2011-02-21T12:56:14.113 に答える
1

あなたはこれに興味があるかもしれません。このエラーも見つかりました。hibernate.cfg.xml のテーブルの名前を「メッセージ」から「MESSAGE」に変更すると、スキーマを見つけることができました。

これもうまくいくかどうか教えてください。

于 2011-07-12T11:27:57.497 に答える
1

同じエラーが発生し、エンティティが hibernate.cfg.xml で構成されていて、hbm2ddl を使用してテーブルを生成していたので、検索したところ、エンティティ マッピングに予約語である「POSITION」という名前のフィールドが含まれていることがわかりました。 . 「POS」に変更すると、テーブルが正しく生成されました。

でresultSet反復をデバッグすることにより、テーブルが生成されているかどうかを確認できます

org.dbunit.database.DatabaseDataSet.initialize()。

于 2014-10-03T12:23:41.190 に答える
0

DbUnit クラスはデータベースからデフォルト スキーマを取得します。使用するスキーマがデフォルトでない場合は、.xml ファイル内で目的のスキーマを設定し、他のスキーマの認識オプションを有効にする必要があります。以下の解決策を参照してください。私はそれを作成しました。

Example.xml - 複数のスキーマ

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
    <SCHEMA1.NAME_TABLE id="5" userName="1" />
    <SCHEMA2.NAME_TABLE id="2" roleName="1" />
<dataset>


<?xml version='1.0' encoding='UTF-8'?>
<dataset>
    <PEOPLE.USER id="5" userName="1" />
    <FUNCTIONS.ROLE id="2" roleName="1" />
<dataset>

テストクラス

    @Before
    public void initialize() throws Exception{
        //Insert data into database
        DatabaseOperation.CLEAN_INSERT.execute(getConnection(), getDataSet());
    }

    @After
    public void cleanup() throws Exception{
     //Clean up the database
      DatabaseOperation.DELETE_ALL.execute(getConnection(), getDataSet());
      System.out.println("DELETADO COM SUCESSO!");

    }

    private IDatabaseConnection getConnection() throws Exception{
            // Get the database connection
            Connection con = dataSource.getConnection();
            DatabaseMetaData  databaseMetaData = con.getMetaData();
            DatabaseConnection connection = new DatabaseConnection(con,databaseMetaData.getUserName().toUpperCase());
            //Allow multiple schemas to be used
            connection.getConfig().setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
            return connection;    
    }

    private IDataSet getDataSet() throws Exception{
        //Get file to insert
        File file = new File("src/test/resources/Example.xml");
        return new FlatXmlDataSet(file);
}
于 2019-07-24T17:39:34.040 に答える