Java 如果结果大小大于1,Hibernate将返回重复的值

Java 如果结果大小大于1,Hibernate将返回重复的值,java,hibernate,Java,Hibernate,我在PostgreSQL中有一个简单的表,叫做“transaction\u response”。在这个表中,只有两列:transaction\u id和response\u id 我的数据有两行。两者都具有相同的事务\u id,但响应\u id值不同 我创建了以下Java类来保存这些数据: public class TransactionResponseDAO implements java.io.Serializable { private Integer transactionId;

我在PostgreSQL中有一个简单的表,叫做“transaction\u response”。在这个表中,只有两列:transaction\u id和response\u id

我的数据有两行。两者都具有相同的事务\u id,但响应\u 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配置文件:


在我正在使用的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();
        }
Query q=null;
SessionFactory sFactory=new Configuration().configure(“/conf/hibernate.cfg.xml”).buildSessionFactory();
会话=空;
试一试{
session=sFactory.openSession();
q=session.getNamedQuery(“findTransactionResponseByTransactionId”);
q、 setInteger(“transactionId”,transactionId);
}捕获(例外e){
System.err.println(“运行getStatusTab时出错”);
e、 printStackTrace();
session.close();
sFactory.close();
}
ArrayList结果=(ArrayList)q.list();
session.close();
sFactory.close();
System.out.println(“>>>大小:“+results.Size());
对于(TransactionResponseDAO tr:结果){
系统输出打印项次(tr);
System.out.println();
}
当我运行这段代码时,它会返回两行,这是应该的。但是,当打印出值时。。。两行的响应id相同。因此,出于某种原因,它似乎没有拉入第二个响应的id值


为什么会这样?一如既往,我感谢你的帮助

问题在于hibernate的缓存机制。当hibernate获取第一行并创建对象时,它会通过指定的id列(transactionId)缓存该对象。当hibernate获取第二行时,它认为这是与第一行相同的行,因为这些行具有相同的id,所以从缓存中获取对象(相同的对象),并将其再次放到结果中


如果ColumTransactionID不唯一,请不要将其与id标记映射。

谢谢您的反馈。我所做的是使用了一个复合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>


如果映射类可能包含重复的值,则不应将
transactionId
字段设置为映射类的id。我认为您关于近因的说法是正确的,但这里真正重要的寓意是您的最后一行@沙拉坎同意。transactionId列定义的另一个问题是:如果标记为增量,它如何获得重复的id?我打赌这些行不是由Hibernate插入的,而是由手动或其他进程插入的。@DiogoSantana,我想你说得对。不是我的代码,只是直接通过了。。。啊。而增量只是作为一个试验被扔进去的。它被设置为identity before(如果可能的话)为表提供主属性
<?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>