6

PostgreSQL に「transaction_response」という単純なテーブルがあります。このテーブルには、transaction_id と response_id の 2 つの列しかありません。

そこにあるデータは2行です。両方とも transaction_id は同じですが、response_id の値が異なります。

このデータを保持するために、次の Java クラスを作成しました。

public class TransactionResponseDAO implements java.io.Serializable {
    private Integer transactionId;
    private Integer responseId;

    public Integer getTransactionId() {
        return transactionId;
    }

    public void setTransactionId(Integer transactionId) {
        this.transactionId = transactionId;
    }

    public Integer getResponseId() {
        return responseId;
    }

    public void setResponseId(Integer responseId) {
        this.responseId = responseId;
    }

    public String toString() {
        return "Transaction Id: " + transactionId + "\nResponse Id: " + responseId;
    }
}

次に、「TransactionResponse.hbm.xml」という名前の Hibernate 構成ファイルを作成しました。

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.data.TransactionResponseDAO" table="transaction_response">
        <id name="transactionId" column="transaction_id" type="java.lang.Integer">
            <generator class="increment"/>
        </id>

        <property name="responseId" type="java.lang.Integer">
            <column name="responses_id" />
        </property>

    </class>

    <query name="findTransactionResponseByTransactionId">
        <![CDATA[from com.data.TransactionResponseDAO where transaction_id = :transactionId]]>
    </query>

    <query name="findTransactionResponseByBothIds">
        <![CDATA[from com.data.TransactionResponseDAO where transaction_id = :transactionId 
                 and responses_id = :responseId]]>
    </query>
</hibernate-mapping>

これをテストしているJavaクラスには、次のコードがあります。

Query q = null;
        SessionFactory sFactory = new Configuration().configure("/conf/hibernate.cfg.xml").buildSessionFactory();
        Session session = null;

        try {
            session = sFactory.openSession();
            q = session.getNamedQuery("findTransactionResponseByTransactionId");
            q.setInteger("transactionId", transactionId);
        }catch (Exception e) {
            System.err.println("Error running getStatusTab");
            e.printStackTrace();

            session.close();
            sFactory.close();
        }

        ArrayList<TransactionResponseDAO> results = (ArrayList<TransactionResponseDAO>) q.list();

        session.close();
        sFactory.close();

        System.out.println(">>> Size: " + results.size());

        for (TransactionResponseDAO tr : results) {
            System.out.println(tr);
            System.out.println();
        }

このコードを実行すると、当然のことながら 2 行が返されます。ただし、値を出力すると... response_id は両方の行で同じです。そのため、何らかの理由で 2 番目の response_id 値を取得していないようです。

これは何か理由がありますか?いつものように、私は助けに感謝します!

4

2 に答える 2

14

問題は、休止状態のキャッシュ メカニズムです。hibernate が最初の行をフェッチしてオブジェクトを作成すると、指定された id 列 (transactionId) によってそのオブジェクトがキャッシュされます。hibernate が 2 番目の行をフェッチすると、最初の行と同じ行であると見なされます。これらの行には同じ ID があるため、キャッシュからオブジェクト (同じオブジェクト) を取得し、結果に再度配置します。

列の transactionId が一意でない場合は、id タグでマップしないでください。

于 2013-03-27T17:54:29.573 に答える
0

フィードバックありがとうございます。私がしたことは、代わりにcomposite_idを使用することで、それが修正されました。再度、感謝します!

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.data.TransactionResponseDAO" table="transaction_response">
        <composite-id name="primaryKey" class="com.data.TransactionResponsePK">
            <key-property name="transactionId" column="transaction_id" type="java.lang.Integer" />
            <key-property name="responseId" column="responses_id" type="java.lang.Integer" />
        </composite-id>

    </class>

    <query name="findTransactionResponseByTransactionId">
        <![CDATA[from com.data.TransactionResponseDAO tr where tr.primaryKey.transactionId = :transactionId]]>
    </query>

    <query name="findTransactionResponseByBothIds">
        <![CDATA[from com.data.TransactionResponseDAO tr where tr.primaryKey.transactionId = :transactionId 
                 and tr.primaryKey.responseId = :responseId]]>
    </query>
</hibernate-mapping>
于 2013-03-27T18:15:42.287 に答える