OneToMany关系无效

我的表:

产品 :id,名称

优惠 :id,value,product_id

实体:

@Entity @Table(name="product") public class Product implements Serializable { @OneToMany(mappedBy="product") private Set offers; ... } @Entity @Table(name="offer") public class Offer implements Serializable { @ManyToOne @JoinColumn(name="PRODUCT_ID") private Product product; ... } 

当我尝试从表Product获取一些数据时,我得到一个java.lang.NullPointerException ,这段代码: product.getOffers()返回:

{IndirectSet:未实例化}

如何解决这个问题?

不是错误消息。 print指令导致在底层IndirectSet上调用toString()

当从数据库中读取包含域对象时,TopLink将在实例变量中放置IndirectSet。 将第一条消息发送到IndirectSet后,将从数据库中提取内容并恢复正常的Set行为。

IndirectCollection类型具体实现为不实例化toString()

出于调试目的,#toString()不会触发数据库读取。

但是,对间接集合的任何其他调用(例如size()或isEmpty())都将实例化该对象。

当一个“委托”方法首次调用getDelegate()时,最终会触发数据库读取,而getDelegate()又调用buildDelegate(),它将消息getValue()发送给值持有者。 值持有者执行数据库读取。 将第一条消息发送到IndirectSet后,将从数据库中提取内容并恢复正常的Set行为。

另请参见IndirectList:未实例化

如果您在访问product.getOffers()时获得{IndirectSet: not instantiated} ,那么您很可能在事务之外执行此代码。

默认情况下, @OneToMany@ManyToMany关系是延迟加载的 ,这意味着,为了获得更好的性能,只有当您第一次访问数据时,才会获取数据。 这必须在活动事务中发生。
如果您不在此范围内访问此数据,则无法再访问此数据。 您应该将调用代码放在活动事务中,或者将集合更改为渴望而不是延迟:

 @OneToMany(mappedBy="product", fetch=FetchType.EAGER) 

这就是我做的

 // force load of the set. entity.getSecrets().isEmpty(); System.out.println(entity.getSecrets()); 

这解决了我的问题

@OneToMany(mappedBy =“columnName”,cascade = {CascadeType.ALL},fetch = FetchType.EAGER)