当前位置: 首页 > 面试题库 >

如何在不击中目标表的情况下从JPA ManyToOne映射检索外键?

孔和风
2023-03-14
问题内容

我使用以下两个带注释的类来构建图形:

@Entity
@Table(name = "Edge")
public class Edge
{
    /* some code omitted for brevity */

    @ManyToOne
    @JoinColumn(name = "ixNodeFrom", nullable = false)
    private Node         _nodFrom;

    @ManyToOne
    @JoinColumn(name = "ixNodeTo", nullable = false)
    private Node         _nodTo;

    /* some code omitted for brevity */
}

@Entity
@Table(name = "Node")
public class Node
{
    /* some code omitted for brevity */

    @OneToMany(mappedBy = "_nodTo")
    private Set<Edge>    _rgInbound;

    @OneToMany(mappedBy = "_nodFrom")
    private Set<Edge>    _rgOutbound;

    /* some code omitted for brevity */
}

现在,当我构建图形时,我发出两个查询以从任一表中获取所有行并设置子/父引用,为此我需要存储在Edge表中的ID 。

因为我已经在JPA中定义了两个表之间的关系,所以当JPA提供者 懒惰地
*加载关联的节点时,访问边缘对象以获取两个节点的ID将触发每个边缘两个SQL语句。由于我已经有了节点对象,并且已经从边缘表中加载了ID,因此我想跳过这些查询,因为对于较大的图形,它们要花很长时间。

我尝试将这些行添加到Edge类中,但是后来我的JPA提供程序希望我将一个映射设置为只读,而我似乎找不到一种方法来做到这一点:

@Column(name = "ixNodeTo")
private long _ixNodeTo;

@Column(name = "ixNodeFrom")
private long _ixNodeFrom;

如果有问题,我正在使用Eclipselink和MySQL。


问题答案:

我得到了三个同样有用的好答案,但到目前为止,还没有一个人在公众投票中名列前茅,因此,我在这里将它们合并为一个综合的答案:

a)更改查询

您可以通过更改查询来一次加载整个图,从而使JPA提供者有机会意识到它已经在内存中了并且不需要返回数据库:

List<Node> nodes = em.createQuery(
        "SELECT DISTINCT n FROM Node n LEFT JOIN FETCH n._rgOutbound")
        .getResultList();

b)对FK使用只读字段

如问题所述,将FK加载到它们自己的字段中,如果按照JPA提供者的要求,将这些字段声明为只读的话,也可以执行以下操作:

@Column(name = "ixNodeTo", insertable = false, updatable = false)

c)使用财产访问

如果使用的是 属性访问 而不是 字段访问
,则JPA提供程序还可以认识到它已经具有FK,并且不需要获取引用的对象。简而言之,属性访问意味着您将JPA批注放置在getter上,从而“向”JPA提供者保证您的getter不会访问该对象的其余部分。这个问题的更多细节。这对于Hibernate和Eclipselink都有效,并且在启用编织的情况下也可以工作(假定为原始答案,由我实验确定)。 通过Pascal Thivent_

此外,由于出他的答案帕斯卡点,@ManyToOne相反,我原来的职位,是不是延迟加载,但默认情况下急于加载,并改变将需要编织为好。



 类似资料:
  • 我正在使用实体框架映射一些表,但除非我声明一些列作为主键,否则我无法这样做。 这里的问题是,数据库中的表没有主键,并且有数百万行。我没有创建新Id列的权限。 Obs:如果我将属性添加到诸如

  • 问题内容: 我在Android应用程序上使用Firebase,我知道如何使用EventListener从数据库中获取数据。到目前为止。 我的问题是:我有一个ReciclerView,它显示数据中的信息,但仅当我修改数据库时才显示。如果我关闭该应用程序然后再次打开,它什么也不会显示。然后,我进行一些修改,并将所有元素显示在容器中。 有什么方法可以加载数据而无需等待事件,而是手动获取? 先感谢您。 更

  • 是否可以从索引中删除单个映射类型而不删除整个索引?https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-delete-mapping.html说这已经不可能了,但我觉得这很难相信。有人能解释为什么删除了该功能吗?似乎是基本的东西。 我有一个具有两个映射的索引。我希望能够删除一种映射类型(以及该类型的所有文档)

  • 问题内容: 我想解组一个包含数据集合的xml文件,像这样 我们知道这可以通过两个类完成:人员,使用Castor的人员,JAXB或其他框架。 但是,如果不编写收集类的Persons怎么办? 问题答案: 寻找一种方法来告诉Castor您希望它生成一个Person实例。 http://www.castor.org/how-to-map-a-list-at- root.html

  • 我的项目有问题。我试图创建一个搜索功能,从用户表中搜索用户,但与此同时,我还想从另一个化身表中检索用户化身的相应“url”。我确实想在这两个表之间创建一个硬映射。我怎样才能灵活地使用Hibernate标准呢?两个表都使用“loginID”主键。 我有两个班: 我写的是: 谢谢大家!!

  • 我越来越多地尝试设计和构建我的应用程序,使它们与框架无关。这意味着使用JSR注释而不是Spring注释、JPA2接口等。但是我发现自己有时有很多困难。 例如,目前,我需要检索特定类的所有bean的列表。使用特定于Spring的方法,我可以使用ApplicationContext来,但我试图在不使用Spring应用程序上下文的情况下实现这一点。 是否有与Spring应用程序上下文等效的JSR? Ex