1

i'm trying to change my File entity from byte[] model to Blob.

Original code:

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

New code:

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

    @Lob
    private Blob data;

It works fine, BUT I need to use this entity as Seriazable - use in Wicket pages.. (I can't use a DetachableModel or remove Serialization, because, there is a large model of hibernate entities which have to be serialized..)

Hopefully one of you can help me out.

cbob
  • 13
  • 2

1 Answers1

3

You can make the Blob transient and then it won't be serialized but it will be null upon deserialization:

private transient Blob data;

I think your only other option is to create a separate object for the blob and only reference it in the RawDataEntity and the use a LoadableDetachableModel to reload it upon request.

public class BlobModel extends LoadableDetachableModel<Blob> {

    private int id;

    public BlobModel(int id) {
        this.id = id;
    }

    @Override
    protected Blob load() {
        return dao.getObject(id);
    }
}

An other option is change the serialization for pages that cannot be serialized. First create an interface for those pages:

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

Next create your own serializer:

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;
}
}

Then implement that interface on a page which cannot be serialized and write the two methods. getSerializable() should create an object that implements CustomSerializer so that getUnserializable() return the same page.

and last, use the new serializer in your wicket WebApplication:

    getFrameworkSettings().setSerializer(new CustomSerializer(getApplicationKey()));
Martin
  • 1,274
  • 12
  • 23
  • Is the transient keyword usable in hibernate to persist a field? If I understand hibernate implementation of JPA, it doesn't persist transient fields or Transient annotated field as well as described in http://stackoverflow.com/questions/3976469/is-hibernate-jpa-taking-in-consideration-the-transiant-modifier-not-the-anno – Martin Strejc May 06 '14 at 15:29
  • Yes, transient also means it will not be persisted. Is it possible to change the entity in any way? Because the Blob object cannot be serialized so you have to change something somewhere. Why can't you use a Loadable model for the whole entity? – Martin May 07 '14 at 06:22
  • LoadableDetachableModel doesn't solve persistent. If an object is persisted by hibernate (using hibernate versioning) so all fields have be persisted/managed by hibernate. – Martin Strejc May 08 '14 at 05:30
  • But you can extract the blob and only use an id in this object to access that blob in a separate persisted object. then you can use this object in your wicket page and it can be serialized. Then you can access the blob using it's id with a loadable model. One other option is create your own Serialization method. But I have no experience with that. – Martin May 08 '14 at 07:33
  • Thanks for the reply, is almost perfect. I just found problem that my Entity is inside another Entity and CustomSerializer is applied only to the first .. (second one is serialized by standard java serializer) But I hope, I will resolve it :) – cbob May 16 '14 at 20:09