Ema*_*uel 21 java entity jpa one-to-many
我的表:
产品:id,名称
优惠:id,value,product_id
实体:
@Entity
@Table(name="product")
public class Product implements Serializable {
@OneToMany(mappedBy="product")
private Set<Offer> offers;
...
}
@Entity
@Table(name="offer")
public class Offer implements Serializable {
@ManyToOne
@JoinColumn(name="PRODUCT_ID")
private Product product;
...
}
Run Code Online (Sandbox Code Playgroud)
当我尝试从表中获取一些数据时Product,我得到一个java.lang.NullPointerException,并且这段代码:product.getOffers()返回:
{IndirectSet:未实例化}
如何解决这个问题?
Tom*_*asz 26
这不是错误消息.print指令导致在底层IndirectSet上调用toString().
当从数据库中读取包含域对象时,TopLink将在实例变量中放置IndirectSet.将第一条消息发送到IndirectSet后,将从数据库中提取内容并恢复正常的Set行为.
IndirectCollection类型是专门实现的,不在toString()上实例化:
出于调试目的,#toString()不会触发数据库读取.
但是,对间接集合的任何其他调用(例如size()或isEmpty())都将实例化该对象.
当一个"委托"方法首次调用getDelegate()时,最终会触发数据库读取,而getDelegate()又调用buildDelegate(),它将消息getValue()发送给值持有者.值持有者执行数据库读取.将第一条消息发送到IndirectSet后,将从数据库中提取内容并恢复正常的Set行为.
Pio*_*cki 13
如果您{IndirectSet: not instantiated}在访问时获得的product.getOffers()可能性很大,那么您将在事务之外执行此代码.
默认情况下@OneToMany,@ManyToMany关系是延迟加载的,这意味着,为了获得更好的性能,只有在您第一次访问数据时才会获取数据.这必须在活动事务中发生.
如果您不在此范围内访问此数据,则无法再访问此数据.您应该将调用代码放在活动事务中,或者将集合更改为渴望而不是延迟:
@OneToMany(mappedBy="product", fetch=FetchType.EAGER)
Run Code Online (Sandbox Code Playgroud)
这就是我做的
// force load of the set.
entity.getSecrets().isEmpty();
System.out.println(entity.getSecrets());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20444 次 |
| 最近记录: |