Tabla de Contenidos

Mapear BFILES con Hibernate

En esta wiki se va a describir cómo mapear tipos de datos BFILE de Oracle para trabajar directamente con ficheros en Hibernate/JPA.

Un BFILE no es un fichero, es un puntero a un fichero que se encuentra en un directorio gestionado por Oracle.

Guía detallada

Ficheros que intervienen en el mapeo:

Configuración y uso

De momento esta configuración solo es válida para la LECTURA de BFILEs.


1. Fichero persistence.xml


Sustituir la propiedad hibernate.dialect por:

<property name="hibernate.dialect" value="es.um.atica.hibernate.dialect.FundeWebOracle10gDialect"/>


2. Entidad

- Anotar la entidad que contiene la columna BFILE con:

 @EntityListeners( PreventRemove.class )
 


Elegir una de las siguientes opciones para mapear el BFILE en la entidad.

- [OPCIÓN A] Si el formato de los ficheros a recuperar es conocido y siempre es el mismo:

private byte[] fichero;
  @Column( name = "[NOMBRE_COLUMNA]", updatable = false, insertable = false )
  @Type( type = "es.um.atica.hibernate.type.BFileToByteArrayType" )
  public byte[] getFichero() {
	return fichero;
  }


- [OPCIÓN B] Si el formato de los ficheros a recuperar no es conocido o puede variar:

private OracleBfile fichero;
  @Column( name = "[NOMBRE_COLUMNA]", updatable = false, insertable = false )
  @Type( type = "es.um.atica.hibernate.type.BFileType" )
  public OracleBfile getFichero() {
	return fichero;
  }
 
       //Ejemplo con columna 'fichero'
	@Transient
	public byte[] getFicheroBytes() throws SQLException {
 
		byte[] result = null;
 
		try {
			if ( this.fichero != null && this.fichero.fileExists() ) {
				this.fichero.openFile();
				java.io.ByteArrayOutputStream bao = new java.io.ByteArrayOutputStream();
				java.io.InputStream in = this.fichero.getBinaryStream();
				byte[] buffer = new byte[1024];
				int len = -1;
				while ( ( len = in.read( buffer, 0, buffer.length ) ) > -1 ) {
					bao.write( buffer, 0, len );
					bao.flush();
				}
				bao.close();
				result = bao.toByteArray();
				this.fichero.closeFile();
			}
		} catch ( Exception ex ) {
			throw new SQLException( "Could not read OracleBfile:", ex );
		}
 
		return result;
	}
        //Ejemplo con columna 'fichero'
        @Transient
	public String getFicheroName() throws SQLException {
 
		String result = null;
 
		if ( this.fichero != null && this.fichero.fileExists() ) {
			result = this.fichero.getName();
		}
 
		return result;
	}


3. Manejador

Ejemplo con columna byte[] en FundeWeb 2.0 (OPCIÓN A)

//ejemplo simplificado con entidad 'f' y columna 'fichero' 
InputStream stream = new ByteArrayInputStream( f.getFichero() ); 
StreamedContent fileDownload = new DefaultStreamedContent( stream, "application/pdf", "miFichero.pdf");


Ejemplo con columna OracleBfile en FundeWeb 2.0 (OPCIÓN B)

//ejemplo simplificado con entidad 'f' y columna 'fichero'
InputStream stream = new ByteArrayInputStream( f.getFicheroBytes() ); 
String mimeType = java.net.URLConnection.guessContentTypeFromName( f.getFicheroName() );
 
StreamedContent fileDownload = new DefaultStreamedContent( stream, mimeType, f.getFicheroName() );


Como se puede observar, la configuración de la OPCIÓN A es más simple.
Como contrapartida, tendremos que gestionar desde el manejador el nombre y el mimetype del fichero a descargar.
Esta configuración es OPCIONAL cuando el tipo de archivo apuntado es fijo y conocido.

La configuración de la OPCIÓN B, no es tan directa como la anterior, pero permite recuperar desde base de datos tanto el nombre como la extensión del fichero apuntado por el BFILE.
Esta configuración es OBLIGATORIA cuando el tipo de archivo apuntado puede variar.
Esta configuración es OPCIONAL cuando el tipo de archivo apuntado es fijo y conocido.

Se deja a criterio del programador usar una opción de mapeo u otra.

4. Permisos a los directorios

Para poder acceder a los ficheros desde los diferentes entornos de nuestra aplicación habrá que solicitar, via JIRA a SISTEMAS (proyecto BD - DJ-AT-SIST-BD),
permisos de lectura para el usuario JV_ de nuestra aplicación a los directorios apuntados por los BFILEs.

Pueden encontrarse los directorios apuntados haciendo una consulta a la tabla que contiene el BFILE.
El BFILE aparecerá con formato:

bfilename('DIRECTORIO','NOMBRE_FICHERO')

.
Ante cualquier duda al respecto, poneos en contacto con MNCS.

Referencias

LOBs tips

PASO DE BLOBs A BFILEs.

Trabajo con bfile


RAMON GINEL GEA 01/02/2021 13:19