休眠一对一:getId() 不获取整个对象

2022-08-31 14:20:28

我想获取一对一关系的ID,而无需加载整个对象。我认为我可以使用延迟加载来执行此操作,如下所示:

class Foo { 
    @OneToOne(fetch = FetchType.LAZY, optional = false)
    private Bar bar; 
}


Foo f = session.get(Foo.class, fooId);  // Hibernate fetches Foo 

f.getBar();  // Hibernate fetches full Bar object

f.getBar().getId();  // No further fetch, returns id

我希望f.getBar()触发另一个获取。我希望休眠给我一个代理对象,允许我调用.getId(),而无需实际获取Bar对象。

我做错了什么?


答案 1

使用属性访问策略

而不是

@OneToOne(fetch=FetchType.LAZY, optional=false)
private Bar bar;

private Bar bar;

@OneToOne(fetch=FetchType.LAZY, optional=false)
public Bar getBar() {
    return this.bar;
}

现在它工作正常!

如果调用任何不是标识符 getter 方法的方法,则将初始化代理。但它只是在使用属性访问策略时起作用。请记住这一点。

请参见: 休眠 5.2 用户指南


答案 2

只是为了添加到Arthur Ronald F D Garcia的帖子中:您可以通过(或弃用)强制访问财产,请参阅 http://256stuff.com/gray/docs/misc/hibernate_lazy_field_access_annotations.shtml@Access(AccessType.PROPERTY)@AccessType("property")

另一种解决方案可能是:

public static Integer getIdDirect(Entity entity) {
    if (entity instanceof HibernateProxy) {
        LazyInitializer lazyInitializer = ((HibernateProxy) entity).getHibernateLazyInitializer();
        if (lazyInitializer.isUninitialized()) {
            return (Integer) lazyInitializer.getIdentifier();
        }
    }
    return entity.getId();
}

也适用于分离的实体。


推荐