我有一个看起来像这样的课程:
@Entity
public class EdgeInnovation {
@Id
public long id;
@ManyToOne
public NodeInnovation destination;
@ManyToOne
public NodeInnovation origin;
}
和另一个看起来像这样的人:
@Entity
public class NodeInnovation {
@Id
public long id;
@OneToOne
public EdgeInnovation replacedEdge;
}
所以每个表映射到另一个,因此一个实体将引用将引用更多实体的其他实体,以便最终将有许多实体将从数据库中获取。有没有办法只获取密钥的值(整数/长整数),而不是它所引用的实体?像这样的东西:
@ManyToOne(referToThisTable="NodeInnovation")
@Entity
public class EdgeInnovation {
@Id
public long id;
@ManyToOne(referToTable="NodeInnovation")
public Long destination;
@ManyToOne(referToTable="NodeInnovation")
public Long origin;
}
和
@Entity
public class NodeInnovation {
@Id
public long id;
@OneToOne(referToTable="EdgeInnovation")
public Long replacedEdge;
}
这是一个例子。我希望这些东西是绿色的,我把所有的东西都用红色随之而来。这会浪费从磁盘读取的内存和时间。
答案 0 :(得分:4)
您只需将外键映射为基本映射而不是关系:
@Entity
public class EdgeInnovation {
@Id
public long id;
@Column(name="DESTINATION_ID")
public Long destination;
@Column(name="ORIGIN_ID")
public Long origin;
}
或者您可以访问EdgeInnovation中的ID和引用的实体,但您需要决定使用哪个来设置映射:
@Entity
public class EdgeInnovation {
@Id
public long id;
@Column(name="DESTINATION_ID", updatable=false, insertable=false)
public Long destination_id;
@ManyToOne
public NodeInnovation destination;
@Column(name="ORIGIN_ID", updatable=false, insertable=false)
public Long origin_id;
@ManyToOne
public NodeInnovation origin;
}
在上面的示例中,origin_id是只读的,而原始引用用于设置表中的外键。但是,应该对两个字段进行任何更改,以使对象映射保持彼此同步。
另一种方法是使用提供程序的本机代码来查找引用是否是惰性且未触发,然后获取外键值。如果它已被触发,您可以使用该引用来获取ID值,因为它不会导致查询获取任何内容。这是您必须查看EclipseLink源代码的内容。
答案 1 :(得分:1)
对不起,我不能发表评论,所以我把它放在这里, 我认为它应该是那样的
@Entity
public class EdgeInnovation {
@Id
public long id;
@ManyToOne
public NodeInnovation destination;
@ManyToOne
public NodeInnovation origin;
}
另一类是:
@Entity
public class NodeInnovation {
@Id
public long id;
@OneToMany(mappedBy="origin")
public List<EdgeInnovation> replacedEdges;
}
如果我的情况不对,那么(你可以用关系画出你的课程,这样我可以直接说出来吗?)
答案 2 :(得分:0)
为什么不在new construction
中使用JPA中的NodeInnovation
和自定义构造函数?基本上,在NodeInnovation
中创建一个瞬态属性,以便在只需要EdgeInnovation
id时使用:
@Entity
public class NodeInnovation {
@Id @GeneratedValue private Long id;
private Integer type;
@OneToOne
private EdgeInnovation replacedEdge;
@Transient
private Long replacedEdgeId;
public NodeInnovation() {}
public NodeInnovation(Long id, Integer type, Long replacedEdgeId ) {
this.id = id;
this.type = type;
this.replacedEdgeId = replacedEdgeId;
}
...
}
像这样使用它:
NodeInnovation n = em.createQuery("select new NodeInnovation(n.id, n.type, n.replacedEdge.id) from NodeInnovation n where n.id = 20", NodeInnovation.class).getSingleResult();
您没有说明如何选择NodeInnovation
,无论是直接选择还是通过加入,但无论哪种方式都是JPQL或CriteriaBuilder查询中的new NodeInnovation
。