我在PostgreSQL中有一个名为“transaction_response”的简单表。在此表中,只有两列:transaction_id和response_id。
我在那里的数据有两行。两者都具有相同的transaction_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();
}
当我运行此代码时,它会返回两行,就像它应该的那样。但是,在打印出值时...两行的response_id相同。因此,由于某种原因,它似乎没有引入第二个response_id值。
这是为什么?一如既往,我感谢您的帮助!
答案 0 :(得分:10)
问题是hibernate的缓存机制。当hibernate获取第一行并创建一个对象时,它会通过指定的id列(transactionId)缓存该对象。当hibernate获取第二行时,它认为该行与第一行相同,因为这些行具有相同的id,从缓存中获取对象(同一个对象)并将其再次放在结果上。
如果colum transactionId不是唯一的,请不要将其映射为id标记。
答案 1 :(得分: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>