Java 在访问关联实体';身份证

Java 在访问关联实体';身份证,java,hibernate,orm,proxy,lazy-loading,Java,Hibernate,Orm,Proxy,Lazy Loading,我的Hibernate实体如下所示(getter和setter被省略): 据我所知,调用不应该往返到数据库,因为Id存储在EntityA表中,代理应该只返回该值。但是,在我的例子中,这会生成一条SQL语句,它获取EntityB,然后才返回Id 我怎样才能调查这个问题?这种不正确行为的可能原因是什么 据我所知,调用不应该往返到数据库,因为Id存储在EntityA表中,代理应该只返回该值 使用属性访问类型。您正在经历的行为是字段访问类型的“限制”。以下是Emmanuel Bernard对此的解释:

我的Hibernate实体如下所示(getter和setter被省略):

据我所知,调用不应该往返到数据库,因为Id存储在EntityA表中,代理应该只返回该值。但是,在我的例子中,这会生成一条SQL语句,它获取EntityB,然后才返回Id

我怎样才能调查这个问题?这种不正确行为的可能原因是什么

据我所知,调用不应该往返到数据库,因为Id存储在EntityA表中,代理应该只返回该值

使用属性访问类型。您正在经历的行为是字段访问类型的“限制”。以下是Emmanuel Bernard对此的解释:

这是不幸的,但也是意料之中的。这是现场级访问的限制之一。 基本上,我们无法知道getId()实际上只访问id字段。所以我们需要加载整个对象以确保安全

因此,将代码更改为:

@Entity
public class EntityA {
    private EntityB parent;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    public EntityB getParent() {
        return parent; 
    }
    ...
}

@MappedSuperclass
public class SuperEntity {
    private long itemId;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    public long getItemId() { 
        return itemId;
    }
    ...
}
相关问题
工具书类
  • (如果这个问题能够解决)

您所说的很有意义-由于EntityA包含父ID,因此不会产生DB命中。我只是不确定getParent()调用是否实际加载EntityB对象,而不管您感兴趣的是否只是ID。您可以尝试标记子集合(以及任何其他字段)如果您想保存数据库命中率,请将其设置为Lazy

@Entity
public class EntityB : SuperEntity {
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    @Fetch(FetchMode.SUBSELECT)
    @JoinColumn(name = "parent_id")
    private Set<EntityA> children;
}
@实体
公共类实体B:超级实体{
@OneToMany(mappedBy=“parent”,fetch=FetchType.LAZY)
@Fetch(FetchMode.SUBSELECT)
@JoinColumn(name=“parent\u id”)
私人儿童;
}
至于Hibernate:

自Hibernate 5.2.12以来已更改。

OneToMany默认为懒惰。天哪,谢谢,我从未想到会出现这样的问题。HHH-3718最终得到了修复:
@Entity
public class EntityA {
    private EntityB parent;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    public EntityB getParent() {
        return parent; 
    }
    ...
}

@MappedSuperclass
public class SuperEntity {
    private long itemId;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    public long getItemId() { 
        return itemId;
    }
    ...
}
@Entity
public class EntityB : SuperEntity {
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    @Fetch(FetchMode.SUBSELECT)
    @JoinColumn(name = "parent_id")
    private Set<EntityA> children;
}