【问题标题】:Wicket & Hibernate entity with a Blob带有 Blob 的 Wicket 和 Hibernate 实体
【发布时间】:2014-06-21 23:57:43
【问题描述】:

我正在尝试将我的 File 实体从 byte[] 模型更改为 Blob。

原码:

@Entity
@Table(name="raw_data")
public class RawDataEntity extends DomainObject {
  @Lob
  private byte[] data;

新代码:

@Entity
@Table(name="raw_data")
public class RawDataEntity extends DomainObject {

    @Lob
    private Blob data;

它工作正常,但我需要将此实体用作 Seriazable - 在 Wicket 页面中使用.. (我不能使用 DetachableModel 或删除序列化,因为有一个很大的休眠实体模型需要序列化..)

希望你们中的一个可以帮助我。

【问题讨论】:

    标签: hibernate serialization blob wicket


    【解决方案1】:

    您可以使 Blob 瞬态,然后它不会被序列化,但在反序列化时它将为空:

    private transient Blob data;
    

    我认为您唯一的其他选择是为 blob 创建一个单独的对象,并仅在 RawDataEntity 中引用它,并使用 LoadableDetachableModel 根据请求重新加载它。

    public class BlobModel extends LoadableDetachableModel<Blob> {
    
        private int id;
    
        public BlobModel(int id) {
            this.id = id;
        }
    
        @Override
        protected Blob load() {
            return dao.getObject(id);
        }
    }
    

    另一个选项是更改无法序列化的页面的序列化。首先为这些页面创建一个界面:

    public interface CustomSerialize {
        Serializable getSerializable(Object object);
        Object getUnserializable(Object object);
    }
    

    接下来创建你自己的序列化器:

    public class CustomSerializer extends JavaSerializer {
    public CustomSerializer(String applicationKey) {
        super(applicationKey);
    }
    
    @Override
    public byte[] serialize(Object object) {
        if (object instanceof CustomSerialize) {
            super.serialize(((CustomSerialize) object).getSerializable(object));
        }
        return super.serialize(object);
    }
    
    @Override
    public Object deserialize(byte[] data) {
        Object object = super.deserialize(data);
        if (object instanceof CustomSerialize) {
            return ((CustomSerialize) object).getUnserializable(object);
        }
        return object;
    }
    }
    

    然后在无法序列化的页面上实现该接口并编写这两个方法。 getSerializable() 应该创建一个实现 CustomSerializer 的对象,以便 getUnserializable() 返回相同的页面。

    最后,在您的 wicket WebApplication 中使用新的序列化程序:

        getFrameworkSettings().setSerializer(new CustomSerializer(getApplicationKey()));
    

    【讨论】:

    • 临时关键字是否可以在休眠中用于持久化字段?如果我了解 JPA 的休眠实现,它不会保留瞬态字段或瞬态注释字段,正如stackoverflow.com/questions/3976469/… 中所述
    • 是的,瞬态也意味着它不会被持久化。是否可以以任何方式更改实体?因为 Blob 对象无法序列化,所以您必须在某处进行更改。为什么不能对整个实体使用可加载模型?
    • LoadableDetachableModel 不能解决持久性问题。如果一个对象被 hibernate 持久化(使用 hibernate 版本控制),那么所有字段都由 hibernate 持久化/管理。
    • 但是您可以提取 blob 并仅使用此对象中的 id 来访问单独的持久对象中的该 blob。然后你可以在你的检票口页面中使用这个对象,它可以被序列化。然后,您可以使用带有可加载模型的 id 访问 blob。另一种选择是创建自己的序列化方法。但我没有这方面的经验。
    • 感谢您的回复,几乎完美。我刚刚发现我的实体在另一个实体中的问题,并且 CustomSerializer 仅应用于第一个 ..(第二个由标准 java 序列化程序序列化)但我希望,我会解决它:)
    猜你喜欢
    • 1970-01-01
    • 2017-11-15
    • 2010-10-31
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多