Han*_*etz 13 java jpa eclipselink
我有以下两个用于构建图形的带注释的类:
@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 */
}
Run Code Online (Sandbox Code Playgroud)
现在,当我建立图,我发出了两次查询或者从表获取所有行,并成立了父/子引用,为此我需要存储在的ID Edge
表.
因为我已经定义JPA中的两个表之间的关系,访问边缘对象来获取两个节点的IDS触发每边两个SQL语句,当JPA提供商懒洋洋*加载相关联的节点.因为我已经有节点对象和IDS已经从边缘表中加载,我想跳过这些查询,因为他们需要一个相当长的时间,更大的图形.
我尝试将这些行添加到Edge
类中,但是我的JPA提供者希望我将一个映射设置为只读,而我似乎无法找到如何执行此操作的方法:
@Column(name = "ixNodeTo")
private long _ixNodeTo;
@Column(name = "ixNodeFrom")
private long _ixNodeFrom;
Run Code Online (Sandbox Code Playgroud)
我正在使用Eclipselink和MySQL,如果重要的话.
**@ManyToOne
实际的默认行为是急切加载,请参阅Pascal的回答*
Han*_*etz 15
我得到了三个同样有帮助的好答案,现在没有人通过公众投票渗透到最高层,所以我将它们合并在一起作为一个全面的答案:
您可以通过更改查询来立即加载整个图形,从而使JPA提供程序有机会意识到它已经拥有内存中的所有内容,而不需要返回到DB:
List<Node> nodes = em.createQuery(
"SELECT DISTINCT n FROM Node n LEFT JOIN FETCH n._rgOutbound")
.getResultList();
Run Code Online (Sandbox Code Playgroud)
(通过axtavt)
如果像JPA提供者要求的那样将字段声明为只读字段,那么将FK加载到他们自己的字段中(如问题中所述)也将起作用,如下所示:
@Column(name = "ixNodeTo", insertable = false, updatable = false)
Run Code Online (Sandbox Code Playgroud)
(通过bravocharlie)
如果您使用属性访问而不是字段访问,JPA提供程序也有机会意识到它已经拥有FK并且不需要获取引用的对象.简而言之,属性访问意味着您将JPA注释放在getter上,从而"承诺"JPA提供者,您的getter将不会访问该对象的其余部分.这个问题的更多细节.这适用于Hibernate,对于Eclipselink,它将起作用(在原始答案中假定,由我实验确认)并启用编织.(通过Pascal Thivent)
此外,如帕斯卡在他的回答指出,@ManyToOne
相反,我原来的职位,是不是延迟加载,但默认情况下急于加载,并且改变它需要编织为好.
小智 12
你有没有尝试过
@Column(name = "ixNodeTo", insertable = false, updatable = false)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15359 次 |
最近记录: |