我最近在Web應用程序的一般升級中將Spring 2.5升級到3.2,將Hibernate 3升級到4.2.8。現在大多數情況都在起作用,但是有一個Criteria事務不起作用,讓我感到困惑。新版本沒有返回任何結果(但沒有錯誤),而舊版本正確檢索了請求的值。休眠從3升級到4:標準事務停止工作
該代碼在舊版本和新版本中是相同的,並且我已驗證達到它的參數是相同的。下面是Java代碼:
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ViewingResource.class);
criteria.createCriteria("viewings","currentViewings");
criteria.add(Property.forName("currentViewings.id").eq(viewingId));
ViewingResource result = (ViewingResource)criteria.uniqueResult();
ViewingResource是我的實體,它的定義如下:
@Entity
@DiscriminatorValue("viewing")
public class ViewingResource extends AbstractInformationResource {
private static final long serialVersionUID = -4569093742552159052L;
@OneToOne(targetEntity = Attribute.class, fetch = FetchType.LAZY)
@JoinColumn
private Attribute primaryAttribute;
@OneToMany(targetEntity = Viewing.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval=true)
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
@JoinTable(name = "informationresource_viewings")
@OrderBy("sort")
private Set<ResourceViewing> viewings;
public Set<ResourceViewing> getViewings() {
return viewings;
}
public Attribute getPrimaryAttribute() {
return primaryAttribute;
}
}
而對於抽象類它擴展:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name = "type",
discriminatorType = DiscriminatorType.STRING
)
@Table(name = "informationresource")
abstract public class AbstractInformationResource extends PersistentEntity<String> {
private static final long serialVersionUID = 8709376067232042462L;
@Id @GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private int sort;
public String getId() {
return id;
}
public String getName() {
return name;
}
public int getSort() {
return sort;
}
}
和原來PersistentEntity只是一個帶有id和沒有註釋的Serializable的擴展。
我啓用休眠日誌,發現問題可在標註在Hibernate中3和4之間的工作方式,對Hibernate生成的SQL字符串以這種方式有所不同:
休眠3:
select
... (maps to all columns)
from
informationresource this_
inner join
informationresource_viewings viewings3_
on this_.id=viewings3_.informationresource_id
inner join
Viewing currentvie1_
on viewings3_.viewings_id=currentvie1_.id
where
this_.type in (
'viewing', 'directory'
)
and currentvie1_.id=?
而在休眠4,生成的SQL執行沒有聯接:
select
... (maps to all columns, except type, attributeType and fieldName)
from
informationresource this_,
informationresource_viewings viewings3_,
Viewing currentvie1_
where
this_.id=viewings3_.informationresource_id
and viewings3_.viewings_id=currentvie1_.id
and this_.type='viewing'
and currentvie1_.id=?
任何提示,可以幫助我解決這個問題,提前?我目前的猜測是,也許我跳過了一些自Hibernate 3以來已經更改或修改的註釋定義,但到目前爲止,我還沒有能夠以我聲明的方式發現任何非法的東西 - 並且我嘗試修改@Join迄今爲止未能成功。
編輯。在玩了一段時間後,我發現問題可能與抽象類的@DiscriminatorColumn有關。我發現問題在於,我對這種請求的類型從來不會「查看」,而是「目錄」。在舊生成的SQL我不得不產生兩種類型:
this_.type in (
'viewing', 'directory'
)
但在新的SQL,這是受限於「觀察」:
and this_.type='viewing'
我在新的SQL這一行已經改變,它返回我需要的正確值。列類型只有這兩個值,'查看'和'目錄'。所以我現在的問題是如何讓Criteria繼續詢問類型,而不是強制「查看」類型。