2010-01-18 6 views
8

J'ai essayé d'enregistrer le fichier dans MySQL en utilisant blob avec hibernate3. Mais je l'ai toujours java.lang.UnsupportedOperationException: Blob ne peut être manipulé de création de la session org.hibernate.lob.BlobImpl.excep (BlobImpl.java:127)Enregistrer blob sur DB en mode hibernation

Voici un code.

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> 

Aidez-moi s'il vous plaît. Où est-ce que je me trompe?

+0

Votre mappage montre un com.uni.domain.FleType, mais votre classe est nommée PhotoType. Était-ce une faute de frappe? Pouvez-vous poster votre stacktrace? –

Répondre

4

Si vous regardez le code source de mise en veille prolongée pour BlobImpl, vous trouverez que la méthode getBytes ne sont pas mises en œuvre, et seulement avant d'exception:

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 

au lieu de getBytes(), vous devez utiliser getBinaryStream()

Exemple d'utilisation:

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

Nous aimerions avoir des indications sur la façon dont getBinaryStream devrait être utilisé. –

2

Si vous l'utilisez avec Spring, il existe un support intégré pour Spring. DefaultLobHandler C'est une question de config de le faire fonctionner. Sample Code pour se référer, pas beaucoup a changé depuis les anciennes versions de Spring.

Questions connexes