星期四, 6月 28, 2007

Hibernate oracle blob 備忘記

這次備忘記主要是記載處理 Hibernate blob 在 Oracle 出現的問題.

以及在 mapping file 裡使用 date 做 mapping 時, 進入 database 後, 時分秒會不見了的問題,
故此時要使用 timestamp 取代做 mapping , 而在 java 中仍使用 java.util.Date.
另一個問題是當 entity 在 detached 狀態時, java.sql.Timestamp 在經過 XMLEncoder 轉換時,
由於 XMLEncoder 並不支持 java.sql.Timestamp 的問題.


開始備忘記:
[1]
處理 Hibernate oracle blob
[2] 處理 XMLEncoder java.sql.Timestamp

[1] 處理 Hibernate oracle blob:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"
http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="test.joeyta">
<class name="Image" table="image_table">
<id name="id">
<generator class="seqhilo"/>
<param name="sequence">my_sequence</param>
<generator
</id>
<property name="photoBlob" column="photo" type="blob" />
</class>
</hibernate-mapping>


public class Image {
private Integer id;


private byte[] phto;


public Blob getPhotoBlob(){
return Hibernate.createBlob(this.photo);
}

public void setPhotoBlob(Blob photoBlob){
this.photo = OracleBlobUtil.toByteArray(photoBlob);
}


public Integer getId() {
return id;
}


public void setId(Integer id) {
this.id = id;
}


public byte[] getPhoto() {
return photo;
}


public void setPhoto(byte[] photo) {
this.photo = photo;
}


}

public class OracleBlobUtil {
public static byte[] toByteArray(Blob fromBlob){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
if(fromBlob != null){
byte[] buf = new byte[1000];
InputStream is = fromBlob.getBinaryStream();
try {
int dataSize;
while ((dataSize = is.read(buf)) != -1) {
baos.write(buf, 0, dataSize);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
}
}
}
return baos.toByteArray();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
if (baos != null) {
baos.close();
}
} catch (IOException e) {
}
}
}
}

[2] 處理 XMLEncoder java.sql.Timestamp:
只要更改 Entity bean 的 相關 getter 將 Timestamp 轉成 Date
public Date getLastUpdate() {
if(lastUpdate != null && lastUpdate instanceof Timestamp){
lastUpdate = new Date(lastUpdate.getTime());
}
return lastUpdate;
}


以下是 XMLEncoder 的實作:
public class BeanXMLConverter {

public String beanToXml(Object object) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XMLEncoder xe = new XMLEncoder(new BufferedOutputStream(baos));
xe.writeObject(object);
xe.close();
try{
return baos.toString("UTF-8");
} catch (UnsupportedEncodingException uee){
System.out.println("["+this.getClass().getName()+"]"+uee);
}
return baos.toString();
}


public Object xmlToBean(String xmldata) {
ByteArrayInputStream bais;
try{
bais = new ByteArrayInputStream(xmldata.getBytes("UTF-8"));
} catch (UnsupportedEncodingException uee){
bais = new ByteArrayInputStream(xmldata.getBytes());
System.out.println("["+this.getClass().getName()+"]"+uee);
}
XMLDecoder d = new XMLDecoder(new BufferedInputStream(bais));
Object result = d.readObject();
d.close();
return result;
}


}



參考資料:
http://beanlib.sourceforge.net/
http://hansonchar.blogspot.com/2005/06/oracle-blob-mapped-to-byte-in.html








沒有留言: