2014-02-26 55 views
0

我最近在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繼續詢問類型,而不是強制「查看」類型。

回答

0

最後我找到了解決方案,這要感謝我在編輯模塊中指定的提示。

@DiscriminatorFormula("case when type in ('viewing','directory') then 1 else 2 end") 

然後在觀看資源改變鑑別值註釋:

該解決方案從基類建立一個公式來

@DiscriminatorValue("1") 

我真的不知道爲什麼在Hibernate中3我得到了歧視中的所有值,而在Hibernate 4中,值只是這個值,因爲代碼根本沒有改變。所以如果將來有人看到一些類似的行爲,也許這個技巧可以幫助你。