Java/Hibernate:如何检测,如果字段是延迟加载的代理而不是实际数据?

rpppsulh  于 2023-04-04  发布在  Java
关注(0)|答案(4)|浏览(104)

我正在将我的实体转换为DTO,我想为所有字段设置NULL作为DTO值,这些字段是延迟加载的,没有初始化(因为我不想一直传输所有数据)。
我试过了

if (!(entity.getNationality() instanceof HibernateProxy))
    this.setNationalityFromEntity(entity.getNationality());

但似乎没有帮助。欢迎任何建议!
谢谢大家!

w1jd8yoj

w1jd8yoj1#

我们在实体中执行此操作的方式是使用布尔方法,该方法以不会触发延迟加载的方式执行检查。例如,如果我们的实体有一个名为'associatedSomething'的关联实体,则检查该关联实体是否已被延迟加载的方法为:

public boolean isAssociatedSomethingLoaded() {
        if (associatedSomething instanceof HibernateProxy) {
            if (((HibernateProxy)associatedSomething).getHibernateLazyInitializer().isUninitialized()) {
                return false;
            }
        }
        return (getAssociatedSomething() != null);
    }

注意:在检查中不要使用getAssociatedSomething(),这一点很重要,因为这可以确保关联的实体在检查期间不会被延迟加载。

g6ll5ycj

g6ll5ycj2#

这个类总是一个代理,不管它是否被初始化,所以如果你只是检查代理的示例,你每次都要排除它。延迟加载不会导致实体上的代理引用被替换为对新对象的引用,它只是填充字段。
要想知道它是否真的被初始化了,你需要询问它!

if (HibernateProxy.class.isInstance(entity.getNationality())) {
  HibernateProxy proxy = HibernateProxy.class.cast(entity.getNationality());
  if (!proxy.getHibernateLazyInitializer().isUninitialized()) {
    this.setNationalityFromEntity(entity.getNationality());
  }
}
xtupzzrd

xtupzzrd3#

在我看来,仅仅能够为一些不应该用于用例的状态调用getter的可能性是有问题的,但这是另一回事。我建议您实现适当的DTO方法,以避免意外错误。
我创建的Blaze-Persistence Entity Views正是为了这个用例。你本质上是将JPA实体的DTO定义为接口,并将它们应用于查询。它支持Map嵌套的DTO,集合等,基本上是你所期望的一切,最重要的是,它将提高你的查询性能,因为它将生成只获取DTO实际需要的数据的查询。
您的示例的实体视图可能如下所示

@EntityView(Person.class)
interface PersonDto {
  String getNationality();
}

查询可能看起来像这样

List<PersonDto> dtos = entityViewManager.applySetting(
  EntityViewSetting.create(PersonDto.class),
  criteriaBuilderFactory.create(em, Person.class)
).getResultList();
nzkunb0c

nzkunb0c4#

Hibernate中有一个内置的方法。

// Assume that 'myObject' is an instance of a Hibernate proxy
if (Hibernate.isInitialized(myObject)) {
    // The proxy has been initialized, we can safely access its properties
    // ...
} else {
    // The proxy has not been initialized yet, we should load it before accessing its properties
    // ...
}

相关问题