in pure Hibernate i can do:
Blob blob= Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(inputStream, len);
How to do this in jpa (with hibernate as provider)?
In pure hibernate i made user type for blobs, which used setBinaryStream
prepared statement. This solution worked for me perfectly and i'm looking for a way to port it to JPA.
Spring Data JPA is really a set of dependencies that makes it easier to work with a JPA provider. Hibernate is one of several JPA providers. This means you can use Spring Data JPA without using Hibernate (if you really wanted to).
Databases use the data types BLOB (binary large object) and CLOB (character large object) to store large objects, like images and very long texts. JPA and Hibernate provide two kinds of mappings for these types. You can choose if you want to: Materialize the LOB and map it to a byte[] or a String.
@javax. persistence. Lob signifies that the annotated field should be represented as BLOB (binary data) in the DataBase. You can annotate any Serializable data type with this annotation. In JPA, upon persisting (retrieval) the field content will be serialized (deserialized) using standard Java serialization.
JPA alternatives If JPA and Hibernate are not a good fit for your use case, you can use any of the following frameworks: MyBatis, which is a very lightweight SQL query mapper framework. QueryDSL, which allows you to build SQL, JPA, Lucene, and MongoDB queries dynamically.
You can use the @Lob
annotation on your persistent property (Annotation Lob):
@Entity
public class MyEntity {
private byte[] content;
...
@Lob
public byte[] getContent() {
return content;
}
public void setContent(byte[] newContent) {
this.content = newContent;
}
}
In your code you can transform a stream in a byte[] with a code like this:
@Transient
public void setContentFromInputStream(InputStream is) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int l = 0;
do {
l = is.read(buff);
if (l > 0)
{
baos.write(buff, 0, l);
}
} while (l > 0);
is.close();
baos.flush();
baos.close();
content = baos.toByteArray();
}
The @Lob
annotation can also be used with String, in this case you'll obtain a CLOB on the DB
You must pay attention to the size of the byte[]
to avoid OutOfMemoryError
.
To use only streams you must rely on the specific jdbc vendor implementation. For example if you are using Hibernate >= 3.6 you can change they type of MyEntity.content to Blob and write:
MyEntity entity = new MyEntity();
Session session = (Session)entityManager.getDelegate();
Blob newContent = session.getLobHelper().createBlob(inputStream, len);
entity.setContent(newContent);
I hope this can help you
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