web-dev-qa-db-fra.com

Comment écrire Java.sql.Blob sur une entité JPA?

J'ai une entité JPA avec Java.sql.Blob:

@Entity
public class LargeData {

  @Lob
  private Java.sql.Blob data;

  //getters/setters
}

Comment créer une instance de cette entité? Je veux définir Blob avec la méthode setData(), mais comment obtenir Blob depuis JPA? Java.sql.Blob N'est qu'une interface, il existe différentes implémentations pour différentes bases de données, donc je suppose que JPA devrait me donner la bonne implémentation. Comment l'obtenir?

32
amorfis

Utilisez un tableau d'octets:

@Lob
@Column(length=100000)
private byte[] data;

Si vous souhaitez utiliser des flux, créez le blob à l'aide de Hibernate.createBlob(..)

53
Bozho

utiliser un flux de fichiers. Cependant, cela semble avoir diverses complications, selon votre base de données, votre pilote et votre implémentation JPA. J'ai construit une solution générique, lente et qui a échoué avec des fichiers volumineux, puis j'ai trouvé une solution spécifique à Hibernate qui fonctionnait avec Oracle 11.2.0.4

J'utilise Spring Data/JPA, mais le problème semble concerner Hibernate, pas Spring.

Hiberner:

private void testLoadFile() throws SQLException, IOException {


  File f = new File("//C:/tmp/6mb_file.wmv");
  BufferedInputStream fstream = new BufferedInputStream(new FileInputStream(f));

  Session session = entityManager.unwrap(Session.class);
  Blob blob = Hibernate.getLobCreator(session).createBlob(fstream, f.length());

  FileBLOBEntity file = new FileBLOBEntity();

  file.setName("//C:/tmp/6mb_file.wmv");
  file.setTheData(blob);
  blobRepository.saveAndFlush(file);
}

Generic Spring/JPA:

private void testLoadFile() throws SQLException, IOException {

  File f = new File("//C:/tmp/6mb_file.wmv");
  BufferedInputStream fstream = new BufferedInputStream(new FileInputStream(f));

  Blob blob = connection.getConnection().createBlob();
  BufferedOutputStream bstream = new  BufferedOutputStream(blob.setBinaryStream(1));
  // stream copy runs a high-speed upload across the network
  StreamUtils.copy(fstream, bstream);

  FileBLOBEntity file = new FileBLOBEntity();

  file.setName("//C:/tmp/6mb_file.wmv");
  file.setTheData(blob);
  // save runs a low-speed download across the network.  this is where
  // Spring does the SQL insert.  For a large file, I get an OutOfMemory exception here.
  blobRepository.saveAndFlush(file);
}

et pour la récupération:

public void unloadFile() throws SQLException, IOException {

  File f = new File("//C:/tmp/6mb_file.wmv" + "_fromDb");

  FileOutputStream fstream = new FileOutputStream(f);

  FileBLOBEntity file = blobRepository.findByName("//C:/tmp/6mb_file.wmv");
  Blob data = file.getTheData();

  InputStream bstream = data.getBinaryStream();
  StreamUtils.copy(bstream, fstream);

}
4
Phil Horder