I have a JPA entity with java.sql.Blob:
@Entity public class LargeData { @Lob private java.sql.Blob data; //getters/setters }
How to create instance of this entity? I want to set Blob
with setData()
method, but how to get Blob
from JPA? java.sql.Blob
is only interface, there are different implementations for different databases, so I assume JPA should give me right implementation. How to get it?
The Id Annotation. Each JPA entity must have a primary key that uniquely identifies it. The @Id annotation defines the primary key. We can generate the identifiers in different ways, which are specified by the @GeneratedValue annotation.
@Column. Let's start with the @Column annotation. It is an optional annotation that enables you to customize the mapping between the entity attribute and the database column.
If your object does not have an id, but its' table does, this is fine. Make the object an Embeddable object, embeddable objects do not have ids. You will need a Entity that contains this Embeddable to persist and query it.
Use a byte array:
@Lob @Column(length=100000) private byte[] data;
If you want to use streams, create the blob using Hibernate.createBlob(..)
use a file stream. However, this appears to have various complications, depending on your database, driver, and JPA implementation. I built a generic solution, that was slow, and failed with large files, then found a Hibernate-specific solution that worked with Oracle 11.2.0.4
I'm using Spring Data / JPA, but the issue seems to be around Hibernate, not Spring.
Hibernate:
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); }
and for retrieval:
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); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With