[英]How do I retrieve only the ID instead of the Entity of an association?
I have a class that looks something like this: 我有一堂课,看起来像这样:
@Entity
public class EdgeInnovation {
@Id
public long id;
@ManyToOne
public NodeInnovation destination;
@ManyToOne
public NodeInnovation origin;
}
and another one that looks something like this: 另一个看起来像这样:
@Entity
public class NodeInnovation {
@Id
public long id;
@OneToOne
public EdgeInnovation replacedEdge;
}
and so each table map to the other, so one entity will refer to other entities that will refer to more entities and so on, so that in the end there will be many entities that will be fetched from the database. 因此,每个表都映射到另一个表,因此一个实体将引用其他实体,而其他实体将引用更多实体,依此类推,最终,将有许多实体将从数据库中获取。 Is there any way to only get the value (integer/long) of the key and not the entity it refers to?
有什么方法只能获取键的值(整数/长整数),而不是键所指向的实体吗? something like this:
像这样的东西:
@ManyToOne(referToThisTable="NodeInnovation")
@Entity
public class EdgeInnovation {
@Id
public long id;
@ManyToOne(referToTable="NodeInnovation")
public Long destination;
@ManyToOne(referToTable="NodeInnovation")
public Long origin;
}
and 和
@Entity
public class NodeInnovation {
@Id
public long id;
@OneToOne(referToTable="EdgeInnovation")
public Long replacedEdge;
}
Here's an example. 这是一个例子。 I want the stuff in green, I get all the stuff in red along with it.
我想要绿色的东西,我把所有东西都用红色。 This wastes memory and time reading from disk.
这浪费了内存和从磁盘读取的时间。
You would just map the foreign keys as basic mappings instead of Relationships: 您只需将外键映射为基本映射,而不是关系:
@Entity
public class EdgeInnovation {
@Id
public long id;
@Column(name="DESTINATION_ID")
public Long destination;
@Column(name="ORIGIN_ID")
public Long origin;
}
Or you can have access to both the ID and the referenced entity within EdgeInnovation, but you'll need to decide which you want to use to set the mapping: 或者,您可以在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;
}
In the above example, the origin_id is read-only while the origin reference is used to set the foreign key in the table. 在上面的示例中,origin_id是只读的,而origin引用用于在表中设置外键。 Any changes though should be made to both fields to keep the object mappings in synch with each other.
但是,应该对两个字段都进行任何更改,以使对象映射彼此保持同步。
Another alternative is to use the provider's native code to find if the reference is lazy and wasn't triggered, and then get the foreign key value. 另一种选择是使用提供者的本机代码来查找引用是否是惰性的且未被触发,然后获取外键值。 If it has been triggered, you can just use the reference to get the ID value, since it won't cause a query to fetch anything.
如果已触发,则可以使用引用获取ID值,因为它不会导致查询获取任何内容。 This is something you would have to look into EclipseLink's source code for though.
不过,这是您必须研究EclipseLink的源代码的东西。
Sorry, I cant comment so I put it here , I think it should be like that 抱歉,我无法发表评论,所以我把它放在这里,我认为应该是这样
@Entity
public class EdgeInnovation {
@Id
public long id;
@ManyToOne
public NodeInnovation destination;
@ManyToOne
public NodeInnovation origin;
}
And the other class is : 另一类是:
@Entity
public class NodeInnovation {
@Id
public long id;
@OneToMany(mappedBy="origin")
public List<EdgeInnovation> replacedEdges;
}
If I'm getting the situation wrong sorry, (Could you draw your classes with the relations so I can get it straight?) 如果我遇到了错误的情况,对不起,(请问您的课程与关系如何,这样我就可以弄清楚了吗?)
Why not use a new construction
in JPA and a custom constructor in NodeInnovation
? 为什么不在JPA中使用
new construction
并在NodeInnovation
使用自定义构造NodeInnovation
? Basically, create a transient property in NodeInnovation
for use when you only want the EdgeInnovation
id: 基本上,在
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;
}
...
}
Use it like so: 像这样使用它:
NodeInnovation n = em.createQuery("select new NodeInnovation(n.id, n.type, n.replacedEdge.id) from NodeInnovation n where n.id = 20", NodeInnovation.class).getSingleResult();
You didn't say how you were selecting NodeInnovation
, whether directly or through a join, but either way the trick is the new NodeInnovation
in the JPQL or CriteriaBuilder query. 您没有说直接或通过
NodeInnovation
来选择NodeInnovation
方式,但是无论如何,窍门都是JPQL或CriteriaBuilder查询中的new NodeInnovation
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.