我使用的是Hibernate 3.3.1。
我有一個db表(2個字段:id
,name
)。使用Hibernate我爲這個表創建了一個類。休眠生成不必要的查詢
@Entity
@Table(name = "table1")
public class QTable1 implements Serializable {
public QTable1() {
}
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO) //<- modification: to comment this line
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "name")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
更改我要救他們後用session.saveorUpdate
,並將其保存ALL行,已加載表格數據庫。即使他們沒有改變:
update table1 set name='a' where id=1
update table1 set name='b' where id=2
update table1 set name='cc' where id=3 // only this row changed
代碼,修改實體:
final QTable1 item = (QTable1) listTable1.getSelectedValue();
if (item != null) {
item.setName(table1Name.getText());
}
事務代碼:
final Session session = Commons.getSessionFactory().openSession();
session.beginTransaction();
for (Object o : pool.getTable1List().toArray()) {
final QTable1 item = (QTable1) o;
session.saveOrUpdate(item);
}
session.getTransaction().commit();
爲什麼它保存所有的數據?
如果我改變ID的實現(刪除@GeneratedValue(strategy=GenerationType.AUTO)
):
@Id
@Column(name = "id")
private Long id;
它僅保存受影響的行。這就是我所期望的。但沒有@GeneratedValue
如果我嘗試向表中添加新行,我必須手動指定id
,這並不好。
在調試時,我看到使用@GeneratedValue
我沒有在會話PersistanceContext
中的實體entitySnapshotsByKey
,所以它認爲我的實體是新的,並且必須刷新到db。
如何解決這個問題?
UPDATE:
如果我們使用@GeneratedValue
註釋session.saveOrUpdate(item)
只產生update
或insert
查詢。 但是,如果我們不使用@GeneratedValue
註釋session.saveOrUpdate(item)
產生 1)select
爲table1的查詢 2)如果比較的對象是相等的,或者如果我們需要生成update
或insert
查詢不 3)決定。
現在我不明白爲什麼@GeneratedValue
可以防止查詢值。 仍然我不明白爲什麼它使select
查詢如果冬眠有內存中選定的行的副本(entitySnapshotsByKey
)。
但我找到了適合我的溶劑。 我需要的僅僅是用session.merge(item)
替換session.saveOrUpdate(item)
。它會對select
查詢進行隔離並對值進行比較(使用@GeneratedValue
或不使用)。唯一的缺點是潛在的大量查詢。
感謝所有。如果你幫我防止產生select
查詢,會很高興。
您只向我們展示了部分代碼。你能否展示QTable1類的其餘部分,修改實體的代碼以及事務配置? –