Java Lazy Fetch JPA获取JoinCoulmn MappedBy ID

Java Lazy Fetch JPA获取JoinCoulmn MappedBy ID,java,sql,hibernate,jakarta-ee,jpa,Java,Sql,Hibernate,Jakarta Ee,Jpa,情况是这样的 @Entity public class Table_A implements Serializable { //TABLE_A FIELDS @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "TABLE_BID") public Table_B getTable_B() { return table_B; } } 因此,表A和表B之间存

情况是这样的

      @Entity
      public class Table_A implements Serializable {

      //TABLE_A FIELDS

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TABLE_BID")
    public Table_B getTable_B() {
    return table_B;
}
      }
因此,表A和表B之间存在多对一关系 我的问题是我什么时候做一件事

Long tableB_ID = table_A.getTable_B().getTable_BID();
在JPA/Hibernate实现中,fetch是否获取表_B的实例并从中获取相应的ID

从映射列获取ID

提前感谢您的回答。

指的是:前者

Hibernate需要检查引用的
表B
实例是否仍然存在,因此它必须先加载实例,然后才能对其调用
getTable\u BID()



编辑:实际上,更有趣的问题是。它指出Hibernate选择什么取决于访问类型-属性访问(这是您拥有的)不会初始化代理;字段访问(将
@ManyToOne
/your
@Id
放在字段上)初始化代理并从数据库加载实体。

当您为关系指定延迟获取时,它指示在本例中调用方法getTable_B()时访问对象此时,持久性提供程序在数据库中进行选择并填充对象。在Hibernate的情况下,它的行为与持久性提供程序是适当的,因为它使用代理对象,所以在访问相关对象的字段时进行提取,所以getTable_B().getTable_BID()。如果只想访问表_BID,可以进行JPQL查询,或者将此字段映射到表a中,因此

 @Column(name="TABLE_BID")
 public Long getTable_BID() {
    return table_BID;
}

首先,它取决于访问类型,而访问类型本身取决于您对实体的注释方式。如果您注释了getter,那么您使用的是属性访问类型,并且获取ID不会从数据库加载TableB状态。如果对字段进行注释,则使用的是字段访问类型,获取ID将加载TableB状态


这当然取决于实现。但是,您可以通过打开SQL日志、执行代码以及查看是否生成了加载TableB状态的查询来轻松检查它。

这是错误的。调用getTableB()不会加载与TableB关联的状态。它只返回未初始化的代理。只有在对返回的代理调用方法时才会加载状态。这不是真的,它取决于持久性提供程序如何实现它。一种方法是代理对象。从技术上讲,在JPA中,LAZY只是一个提示,JPA提供程序不需要支持它,但OP专门要求Hibernate。Hibernate并没有像你在回答中说的那样做。我将更新我的答案,但我在回答中没有提到Hibernate,我写了持久性提供程序,我不想具体说明,问题是JPA/hibernate在不进入数据库的情况下获取表_BID的值,因为如果实体A被管理,它的值为alreadyHibernate知道该实体是否存在,因为它在联接列中具有该实体的ID(或null)。@JBNizet我怀疑hibernate是否知道它:它没有加载它,因为它是惰性的,所以在那一刻,它不确定它是否存在。(PS:在DB中可能没有外键约束)。@mabi,请忽略命名方案,它是用于qustion@JBNizet朱普,应该读完整的东西(再次);更正了我的答案。@JBNizet谢谢,我认为这对它的行为给出了一个公平的想法。但问题是上面的注释在TableA中创建了一个列(TABLE_BID),但是当它已经在加载的TableA对象中可用时,不需要从tableB对象中获取id。我认为您的代码中有一个错误:
TABLE_a.getTable_B.getTable_BID()
应该是
TABLE_a.getTable_B().getTable_BID()
。请通过改变你的问题来确认我是对的,如果我错了,请发表评论。你是对的。谢谢AndreiThanks,我知道我们可以通过打开SQL日志来检查它。然而,我正在迁移一个被破坏的整个应用程序,我认为我现在无法做到这一点。所以我只是想从专家那里得到一个想法。