Java 一夫一妻的关系不起作用

Java 一夫一妻的关系不起作用,java,jpa,entity,one-to-many,Java,Jpa,Entity,One To Many,我的桌子: 产品:id、名称 报价:标识、价值、产品标识 实体: @Entity @Table(name="product") public class Product implements Serializable { @OneToMany(mappedBy="product") private Set<Offer> offers; ... } @Entity @Table(name="offer") public class Offer implemen

我的桌子:

产品: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;
    ...
}
@实体
@表(name=“产品”)
公共类产品实现可序列化{
@OneToMany(mappedBy=“产品”)
私人套餐;
...
}
@实体
@表(name=“报价”)
公共类提供实现了可序列化{
@许多酮
@JoinColumn(name=“产品标识”)
私人产品;
...
}
当我试图从表
Product
中获取一些数据时,我得到一个
java.lang.NullPointerException
,此代码:
Product.getOffers()
返回:

{间接集:未实例化}


如何修复此问题?

如果在访问
product.getOffers()
时获得
{IndirectSet:not instantized}
,则很可能是在事务之外执行此代码

默认情况下,
@OneToMany
@ManyToMany
关系是相互关联的,这意味着,为了获得更好的性能,只有在首次访问数据时才能获取数据。这必须发生在活动事务中。
如果不在此范围内访问此数据,则不能再访问此数据。您应该将调用代码放在活动事务中,或者将集合更改为惰性:

@OneToMany(mappedBy="product", fetch=FetchType.EAGER)
这就是我所做的

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

这不是一条错误消息。print指令导致在基础上调用toString()

当 从datatabase读取包含域对象。第一个 消息发送到间接集时,内容从 恢复数据库和正常设置行为

具体实现的类型不在toString()上实例化:

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

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

当其中一个“委托”时,将最终触发数据库读取 方法对getDelegate()进行第一次调用,后者依次调用 buildDelegate(),它将消息getValue()发送给值持有者。 值持有者执行数据库读取。第一个 消息发送到间接集时,内容从 恢复数据库和正常设置行为

另请参见

这解决了我的问题


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

我使用Eclipselink 2.5.2版本作为我的ORM供应商,我在一对多JPA映射中遇到了这个问题,同时延迟加载包含的实体。对我有效的解决方法是:-

final List<ContainingEntity> list = Collections.unmodifiableList(new ArrayList<> 
                                    (containerEntity.getContainingEntityList());

您使用的是哪种orm框架??我使用JPA作为orm框架。伊曼纽尔:我想@kiki是在问您使用的是哪种JPA实现。我自己通过JUnit测试进行了实际测试,并总结了最终的EntityTransaction txn=em.getTransaction();txn.begin();和txn.commit(),但我仍然得到相同的行为。因此,您确实在EntityManager的事务中调用了您的逻辑(并且您确实在不离开tx的情况下加载和对象并访问了它),但仍然得到相同的异常?我没有得到“异常”,我得到了{间接集:未实例化}您是对的-这不是异常;但是,我的句子的其余部分正确吗?别这么认为。。。在事务中,您可以在需要时加载数据(rationalle-behind-LAZY),也可以急切地加载数据,这样您就不需要发送来访问它(effective-eanger)。您可以使用FetchType.EAGER、使用JPQL
JOIN FETCH
或在tx中迭代集合的元素来急切地加载对象。然而,所有这些选项都有效地急切地加载整个集合。为什么要调用
entity.getSecrets().isEmpty()
?据我所知,它不会加载您的集合,因为您仍然需要访问对象本身;您发布的sysout应该正好做到这一点(尽管调用对象的
toString
方法只是为了进行延迟加载并不是一个好方法),您可能会这么认为,但EclipseLink似乎没有这样做。不管怎样,它可能是一个“特性”。.isEmpty()强制加载我找到的集合。+1’d此响应;非常有用,因为我想知道为什么eclipselink indirectlist isEmpty()会出现在Java Visual VM中,因为我在用检查列表是否替换indirectlist的JPA查询之后,正在检查、比较和报告性能零和!list.isEmpty()。这绝对解决了我的一个性能问题;一开始访问数据库的次数超过600次,但在最新的实现中,访问数据库的次数仅为5次+一丁点儿。虽然答案是TopLink,但EclipseLink也是如此。@gammay EclipseLink基于TopLink(仅供参考)
@OneToMany(mappedBy = containerEntity, cascade = CascadeType.ALL, fetchType = FetchType.LAZY)
private List<ContainingEntity> containingEntityList;
@ManyToOne
@JoinColumn(name = "container_entity_id")
private ContainerEntity containerEntity;