如何只检索 ID 而不是关联的实体?

How do I retrieve only the ID instead of the Entity of an association?

我有一个 class 看起来像这样:

@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;
}

等等每个 table 映射到另一个,所以一个实体将引用其他实体,这些实体将引用更多实体等等,因此最终将获取许多实体从数据库。有没有办法只获取键的值(integer/long)而不是它所指的实体?像这样:

@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;
}

这是一个例子。我想要绿色的东西,我得到了所有红色的东西。这会浪费内存和从磁盘读取的时间。

对不起,我不能发表评论,所以我把它放在这里, 我觉得应该是这样的

@Entity
public class EdgeInnovation {
    @Id
    public long id;
    @ManyToOne
    public NodeInnovation destination;
    @ManyToOne
    public NodeInnovation origin;
}

另一个class是:

 @Entity
    public class NodeInnovation {
        @Id
        public long id;
        @OneToMany(mappedBy="origin")
        public List<EdgeInnovation> replacedEdges;
    }

如果我理解错了,抱歉,(你能把你的 classes 和关系画出来,这样我就可以弄清楚了吗?)

为什么不在 JPA 中使用 new construction 而在 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

您只需将外键映射为基本映射而不是关系:

@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 是只读的,而原始引用用于设置 table 中的外键。不过,应对这两个字段进行任何更改,以保持对象映射彼此同步。

另一种方法是使用提供者的本机代码来查找引用是否惰性且未被触发,然后获取外键值。如果它已被触发,您可以只使用引用来获取 ID 值,因为它不会导致查询获取任何内容。不过,您必须查看 EclipseLink 的源代码。

我知道我来晚了,但有些人可能会寻找相同问题的答案 - 在您的 JPA 存储库中,您可以这样做:

@Query("SELECT new java.lang.Integer(model.id) FROM #{#entityName} model WHERE model.relationModeFieldlName.id IN :relationModelIds")
List<Integer> findIdByRelationModelIdIn(@Param("relationModelIds") List<Long> relationModelIds);