Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate returns duplicate values if result size is greater than 1

Tags:

java

hibernate

I have a simple table in PostgreSQL called "transaction_response". In this table, there are only two columns: transaction_id and response_id.

The data I have in there are two rows. Both with the same transaction_id, but different response_id values.

I created the following Java class to hold this data:

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;
    }
}

I then created the Hibernate config file called "TransactionResponse.hbm.xml":

<?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>

In a Java class I am testing this with, I have the following code:

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();
        }

When I run this code, it returns two rows back, as it should. However, when printing out the values... the response_id is the same for both rows. So it doesn't seem to be pulling in the second response_id value for some reason.

Any reason why this is? As always, I appreciate the help!

like image 326
Ascalonian Avatar asked Mar 27 '13 17:03

Ascalonian


1 Answers

The problem is the cache mechanism of hibernate. When hibernate fetchs the first row and create a object, it caches that object by the indicated id column (transactionId). When hibernate fetchs the second row, it thinks that is the same row as the first one, because those rows have the same id, get the object from the cache (the same object) and put it again on the result.

If the colum transactionId is not unique, don't map it with id tag.

like image 56
DiogoSantana Avatar answered Sep 22 '22 02:09

DiogoSantana