【问题标题】:JPA - analog of LobCreator from hibernate?JPA - 来自休眠的 LobCreator 的模拟?
【发布时间】:2012-04-20 00:41:54
【问题描述】:

在纯休眠中我可以做到:

Blob blob= Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(inputStream, len);

如何在 jpa 中做到这一点(以 hibernate 作为提供者)?

在纯休眠中,我为 blob 设置了用户类型,它使用了 setBinaryStream 准备好的语句。这个解决方案非常适合我,我正在寻找一种将它移植到 JPA 的方法。

【问题讨论】:

    标签: java hibernate jakarta-ee jpa


    【解决方案1】:

    您可以在持久属性 (Annotation Lob) 上使用 @Lob 注释:

    @Entity
    public class MyEntity {
    
    private byte[] content;
    ...
    
    @Lob
    public byte[] getContent() {
    return content;
    }
    
    public void setContent(byte[] newContent) {
    this.content = newContent;
    }
    }
    

    在您的代码中,您可以使用如下代码转换字节[] 中的流:

    @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();
    }
    

    @Lob 注释也可以与 String 一起使用,在这种情况下,您将在 DB 上获得一个 CLOB

    您必须注意byte[] 的大小以避免OutOfMemoryError

    要仅使用流,您必须依赖特定的 jdbc 供应商实现。 例如,如果您使用 Hibernate >= 3.6,您可以将 MyEntity.content 的类型更改为 Blob 并写入:

    MyEntity entity = new MyEntity();
    Session session = (Session)entityManager.getDelegate(); 
    Blob newContent = session.getLobHelper().createBlob(inputStream, len); 
    entity.setContent(newContent);
    

    希望对你有帮助

    【讨论】:

    • 感谢您的回答!但是To use only streams you must rely on the specific jdbc vendor implementation. 是什么意思?在纯休眠中,我为 blob 设置了用户类型,它使用了 setBinaryStream 准备好的语句。这个解决方案非常适合我,我正在寻找一种将它移植到 JPA 的方法。
    • 我提供的代码是纯 JPA,但是使用 JPA 不能将 InputStream 映射到 DB 列,此代码将不起作用:@Lob InputStream getContent()。要使用 InputStream 而不将 byte[] 加载到内存中,您必须依赖您正在使用的 JPA 实现(在您的情况下为 Hibernate)。无法像使用 Hibernate API 那样仅使用 JPA 2.0 API 来使用 InputStream 处理 BLOB
    • 请多多包涵。我如何依靠休眠来做到这一点?
    • 如果你使用 Hibernate >= 3.6 你可以写:Session session = (Session)entityManager.getDelegate(); LobHelper helper = session.getLobHelper(); Blob content = helper.createBlob(inputStream, len); 。然后您可以将属性 MyEntity.content 的类型设置为 Blob 并使用您的 Blob 进行设置。我正在编辑我的帖子以包含此解决方案
    【解决方案2】:

    如果你想要将任何序列化的对象保存到一个列中,将数据库中的列类型设置为blob,使用Hibernate提供的SerializationHelper类,并将这段代码放在你的bean类中。

    class MyBean{
    
        @Column
        private byte[] object;
    
        @Transient
        public Object getObjectDeserialized() throws IOException, ClassNotFoundException {
            if(this.object == null)
                return new String(); // or another type
            return SerializationHelper.deserialize(this.object);
        }
    
        byte[] getObject() {
            return this.object;
        }
    
        void setObject(byte[] object) {
            this.object = object;
        }
    
        @Transient
        public void setObject(Object obj) throws IOException {
            if(obj != null)
                this.object = SerializationHelper.serialize((Serializable) obj);
        }
    }
    

    【讨论】:

    • 它并不是 Hibernate 真正“提供”的,它是一个内部实现细节。
    【解决方案3】:

    xxxx也许你可以转移你想做的事情。

    类 XXXBean{

    @Column
    private byte[] object;
    
    @Transient
    public Object getObjectDeserialized() throws IOException, ClassNotFoundException {
        if(this.object == null)
            return new String(); // or another type
        return SerializationHelper.deserialize(this.object);
    }
    
    byte[] getObject() {
        return this.object;
    }
    
    void setObject(byte[] object) {
        this.object = object;
    }
    
    @Transient
    public void setObject(Object obj) throws IOException {
        if(obj != null)
            this.object = SerializationHelper.serialize((Serializable) obj);
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-16
      • 1970-01-01
      • 1970-01-01
      • 2017-01-14
      • 1970-01-01
      • 2011-06-29
      • 2016-01-19
      相关资源
      最近更新 更多