2010-01-18 70 views
8

我嘗試使用blob與hibernate3保存文件到MySQL。但我始終有 java.lang.UnsupportedOperationException:斑點可能無法從創建會話 org.hibernate.lob.BlobImpl.excep(BlobImpl.java:127)使用休眠保存blob到數據庫

這裏是一些代碼操作。

package com.uni.domain; 

public class File extends Identifier { 

    private byte[] data; 
    private String contentType; 

    public byte[] getData() { 
     return data; 
    } 

    public File() {} 

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

    public boolean isNew() { 
     return true; 
    } 

    public String getContentType() { 
     return contentType; 
    } 

    public void setContentType(String contentType) { 
     this.contentType = contentType; 
    } 
} 

package com.uni.domain; 

import org.hibernate.Hibernate; 
import org.hibernate.HibernateException; 
import org.hibernate.usertype.UserType; 

import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.Serializable; 
import java.sql.*; 
import java.util.Arrays; 

public class PhotoType implements UserType { 

    public int[] sqlTypes() { 
     return new int[]{Types.BLOB}; 
    } 

    public Class returnedClass() { 
     return byte[].class; 
    } 

    public boolean equals(Object o, Object o1) throws HibernateException { 
     return Arrays.equals((byte[]) o, (byte[]) o1); 
    } 

    public int hashCode(Object o) throws HibernateException { 
     return o.hashCode(); 
    } 

    public Object nullSafeGet(ResultSet resultSet, String[] strings, Object o) throws HibernateException, SQLException { 
     Blob blob = resultSet.getBlob(strings[0]); 
     return blob.getBytes(1, (int) blob.length()); 
    } 

    public void nullSafeSet(PreparedStatement st, Object value, int index) 
      throws HibernateException, SQLException { 
     st.setBlob(index, Hibernate.createBlob((byte[]) value)); 
    } 

    public Object deepCopy(Object value) { 
     if (value == null) return null; 

     byte[] bytes = (byte[]) value; 
     byte[] result = new byte[bytes.length]; 
     System.arraycopy(bytes, 0, result, 0, bytes.length); 

     return result; 
    } 

    public boolean isMutable() { 
     return true; 
    } 

    public Serializable disassemble(Object o) throws HibernateException { 
     return null; . 
    } 

    public Object assemble(Serializable serializable, Object o) throws HibernateException { 
     return null; . 
    } 

    public Object replace(Object o, Object o1, Object o2) throws HibernateException { 
     return null; . 
    } 

<?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="com.uni.domain"> 
    <class name="com.uni.domain.File"> 
     <id name="id"> 
      <generator class="native"/> 
     </id> 
     <property name="data" type="com.uni.domain.FleType"/> 
     <property name="contentType"/> 
    </class> 
</hibernate-mapping> 

請幫助我。我錯在哪裏?

+0

您的映射顯示com.uni.domain.FleType,但您的類名爲PhotoType。這是一個錯字嗎? 你可以發佈你的堆棧跟蹤嗎? – 2010-01-19 14:18:52

回答

4

如果你看看爲BlobImpl休眠源代碼,你會發現這個方法的的getBytes不落實,只着的例外:

69 /** 
    70  * @see java.sql.Blob#getBytes(long, int) 
    71  */ 
    72  public byte[] getBytes(long pos, int len) throws SQLException { 
    73   excep(); return null; 
    74  } 

126 private static void excep() { 
    127   throw new UnsupportedOperationException("Blob may not be manipulated from creating session"); 
    128  } 
    129 

,而不是的getBytes(),你應該使用getBinaryStream()

用法示例:

InputStream inputStream = getContent().getBinaryStream(); 
    int expected = inputStream.available(); 
    byte[] contents = new byte[expected]; 
    int length = inputStream.read(contents); 
    if(length != expected) 
      throw new IOException("Could not read full input"); 
+2

很高興有一些關於如何使用getBinaryStream的指示。 – 2011-09-02 12:36:15

2

如果您在Spring中使用它,Spring中就有內置的支持。 DefaultLobHandler這是一個配置問題讓它工作。 Sample Code來指稱,Spring的舊版本沒有太大的改變。