Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA - analog of LobCreator from hibernate?

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.

like image 254
bunnyjesse112 Avatar asked Apr 06 '12 11:04

bunnyjesse112


People also ask

Can we use Spring data JPA without Hibernate?

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).

How define CLOB in Hibernate?

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.

What is @LOB in JPA?

@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.

What can I use instead of JPA?

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.


1 Answers

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

like image 98
Teg Avatar answered Oct 13 '22 03:10

Teg