2010-04-14 16 views
19

我使用的Ejb3和JPA創建的Clob(基於目前的Hibernate和Oracle 10g)如何在JPA在實施不可知論的方法

我有一個包含CLOB實體

@Entity 
@Table(name = "My_TAB") 
public class ExampleEntity implements java.io.Serializable { 

    private Clob someText; 

    public void setSomeText(Clob someText) { 
     this.someText= someText; 
    } 

    @Column(name = "COLUMN_NAME") 
    public Clob getSomeText() { 
     return this.someText; 
    } 

然後我想保存這種類型的實體。

目前我做這完全

ExampleEntity exampleEntity = new ExampleEntity(); 
exampleEntity.setSomeText(Hibernate.createClob(aStringValue)); 
someOtherDao.save(exampleEntity); 

但是這關係我的代碼休眠工作以下!我特別避免使用Hibernate擴展,只使用JPA註釋。代碼工作,因爲確實Hibernate是我目前的實現。

是否有某種JPA API允許我以通用方式創建clob?所以如果以後我決定切換到Toplink/EclipseLink或其他東西,我不會改變一件事情?

回答

32

有這樣的例子是JPA規範(第9.1.5)

@Column(name="DESC", 
columnDefinition="CLOB NOT NULL", 
table="EMP_DETAIL") 
@Lob 
public String getDescription() { return description; } 

我相信這是對CLOB的標準方式。

+1

您也可能希望'@Basic(fetch = LAZY)'用於延遲加載。 – axtavt 2010-04-14 12:16:05

+1

@Basic(fetch = LAZY)不會在hibernate屬性中工作。至少不是沒有instumentation。 – yannisf 2010-04-14 12:30:47

+3

它不適用於「Oracle 11g R2」 - 我的列定義是@Column(columnDefinition =「CLOB NOT NULL」) @Lob private String notes;但Oracle始終將該列創建爲「CLOB(4000)」。我錯過了什麼嗎? 我正在使用「Hibernate 3.2.0-Final」版本(使用JBoss 6.0-Final)。 – javauser71 2011-03-30 21:21:48

-1

我不確定我會再做一次,但在過去,當我需要將我的應用程序限制爲最廣泛使用的sql類型子集時,我使用單獨的char表實現了二進制對象,並將其存儲爲gzipped並編碼基地臺64。使用XML映射,它是這樣的:

<list name="encodedValue" lazy="true" table="TABLE" cascade="all-delete-orphan"> 
    <key column="TABLE_ID"/> 
    <index column="SEQ"/> 
    <element type="string" column="LINE" length="2000"/> 
</list> 

在代碼中,getValue方法檢索的結果getEncodedValue,串聯它們放在一起,然後進行解碼並解壓它們。作爲一種優化,我在父表上放置了一個簡單的值列,並使用它來適應2000個字符,並且如果需要的話只能轉到子表。

setValue方法將它壓縮並編碼,並將其存儲在簡單的列中,如果它合適的話否則將其分割成子記錄。這也讓你延遲加載,如果數據適合在一個列中,它甚至不需要做單獨的查詢。

如果您知道您的數據庫將支持clobs,可能會過度使用,但在我們的情況下工作得很好。