1

I am using JPA-Hibernate at the moment and want collections to be empty until i call the associated get(). I have been trying for several days now without any success. The reason i want this is because i use Exterialize (or Serialize) and do not always want the collections to be there when sending the serialized string over to the client.

@Entity
public class Thread implements Externalizable {
    static final long serialVersionUID = 9L;


@OneToMany(mappedBy = "parentThread", fetch = FetchType.LAZY)
    @LazyCollection(LazyCollectionOption.EXTRA)
    public Collection<Reply> getReplies() {
        return replies;
    }

And here is the Reply model:

@Entity
public class Reply implements Externalizable {
    static final long serialVersionUID = 8L;

    @ManyToOne
    @JoinColumn(name = "threadId", referencedColumnName = "id", nullable = false)
    public Thread getParentThread() {
        return parentThread;
    }

This code is what i use to serialize the model:

public static final String serialize(Serializable object) throws IOException, ClassNotFoundException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream( baos );
    oos.writeObject( object );
    oos.close();
    BASE64Encoder base64Encoder =  new BASE64Encoder();
    return  new String( base64Encoder.encode(baos.toByteArray()));
}

This is what i use to find the thread objects

models.Thread thread = em.find(models.Thread.class, threadId);

If i use entityManager.find() or a query it still loads the list of replies. So to be extra clear, i would like the collection to be empty when i generate the Entity. Then if i call get() i would like it to fill up.

The following image shows that the replies are stored in the list. They do not have any values in them whitch i presume is because lazy loading means that they are proxy entities that have not really been fetched from the database? Please correct be if i am wrong. As a side note, if it is possible to store the list as an arraylist or some other standard list implementation that would be great. I understand that JPA wants the persistentBag/persistentSet notation since they can have duplicate values which standard implementation do not allow and probably some other reasons aswell. But for serializing the model to the client it would be great not to need the libraries and they also do not seem to work with android because the SSID seem to change in the libraries when using android.

Image with returned replies

I really hope this is possible. Thx in advance!

  • what mechanism do you use to serialize the entities you send over the wire, are you sure they are fetched at the time you call find or is it maybe at serialization-time. – cproinger Apr 28 '13 at 22:18
  • Hello! I filled the question with more information. I am 100% sure that it is at find() since when i am testing i use debugger to stop and check the contents right after find() has been called. Even though i posted my serializing "mechanism" for you if it could help somehow. I have made a workaround that should work as long as the collection is being loaded lazily which for some reason do not work. Here is a link to that question if that one is more solvable: http://stackoverflow.com/questions/16294572/jpa-hibernate-collections-not-lazily-loaded – Mathias Lindblom Apr 30 '13 at 07:44
  • Could it be possible that the debugger triggered the load of the collection when it wanted to display its size? A more reliable way would be to make a test when you do not serialize anything and capture a wireshark trace of the queries to the database. Lazy loading is optional according to the JPA specification, but I have tested it in Hibernate and it works, in Eclipselink only works when load time weaving is enabled. – German Apr 30 '13 at 14:35

1 Answers1

0

i stumbled over this blog: https://sites.google.com/a/pintailconsultingllc.com/java/hibernate-extra-lazy-collection-fetching

  1. i'm not sure if the LazyCollectionOption.EXTRA is the right one for you in this scenario, turn on your sql-logging to see what queries are really executed by hibernate
  2. you annotated a Collection getter so this may be applicable for you (from referenced blog) If the class is org.hibernate.collection.PersistentBag, you're using bag semantics and now the collection will eager load all the items the first time you touch any item in the List.
  3. i wouldn't use ObjectOutputStream in scenarios where it is possible that client and server are upgraded at different times (android class version vs. server class version). you will safe yourself a lot of trouble with these kinds of problems if you serialize to xml or json. For example with xstream (do not use default xstream-xml serialization though because it contains the whole class-name, use aliases) you can tell the serializer which fields to ignore via annotation or explicity before serializing.
cproinger
  • 2,258
  • 1
  • 17
  • 33