2013-04-28 42 views
1

我现在正在使用JPA-Hibernate,并希望集合为空,直到我调用关联的get()。我已经尝试了好几天,但没有取得任何成功。 我想要这样做的原因是因为我使用Exterialize(或者Serialize),并且并不总是希望在将序列化字符串发送到客户端时集合在那里。JPA休眠希望懒加载返回空集合

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

这里是回复模式:

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

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

此代码是我用序列化模式:

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

这是我用它来找到线程对象

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

如果我使用entityMan ager.find()或一个查询,它仍然加载回复列表。所以要更加清楚,我希望收集在我生成实体时为空。然后,如果我打电话get(),我希望它填满。

下图显示答复存储在列表中。他们没有任何价值,我认为是因为懒加载意味着他们是没有真正从数据库中获取的代理实体?如果我错了,请纠正。作为一个侧面说明,如果可以将列表存储为阵列列表或其他标准列表实现,那将是非常好的。我知道JPA需要persistentBag/persistentSet符号,因为它们可以具有标准实现不允许的重复值以及可能的其他原因。但是,为了将模型序列化到客户端,不需要这些库是很棒的,而且它们似乎也不适用于android,因为在使用android时,SSID似乎在库中发生了变化。

Image with returned replies

我真的希望这是可能的。 Thx提前!

+0

你使用什么机制来序列化你通过线路发送的实体,你确定它们是在你调用find时获取的,或者可能是在序列化时。 – cproinger 2013-04-28 22:18:16

+0

你好!我用更多的信息填充了这个问题。我100%肯定它是在find(),因为当我测试时,我使用调试器来停止并在调用find()后检查内容。即使我发布我的序列化“机制”,如果它可以帮助某种方式。我已经做出了一个解决方法,只要该集合正在懒惰地加载,并且由于某种原因不起作用,就应该可以工作。这是一个链接到这个问题,如果那个更加可以解决: http://stackoverflow.com/questions/16294572/jpa-hibernate-collections-not-lazily-loaded – 2013-04-30 07:44:12

+0

有可能调试器触发负载当它想要显示其大小的集合?更可靠的方法是在不序列化任何内容并捕获数据库查询的wireshark trace时进行测试。根据JPA规范,延迟加载是可选的,但是我已经在Hibernate中进行了测试,并且它可以工作,在Eclipselink中只有在启用加载时织入时才起作用。 – German 2013-04-30 14:35:32

回答

0

我绊了这个博客:https://sites.google.com/a/pintailconsultingllc.com/java/hibernate-extra-lazy-collection-fetching

  1. 我不知道如果LazyCollectionOption.EXTRA是适合你在这种情况下,打开你的SQL日志,看看真正执行哪些查询通过休眠
  2. 您注释了一个Collection getter,所以这可能适用于您(来自引用的博客)如果类是org.hibernate.collection.PersistentBag,那么您使用的是bag语义,现在collection将会加载所有的您第一次触摸列表中的任何项目时的项目。
  3. 我不会在场景中有可能是客户端和服务器在不同的时间(机器人类版本与服务器类版本)升级,使用ObjectOutputStream。如果您序列化为xml或json,那么您将为这些类型的问题安全处理很多麻烦。例如,使用xstream(不要使用默认的xstream-xml序列化,因为它包含整个类名,使用别名),您可以告诉序列化程序在序列化之前通过注释或显式忽略哪些字段。