我正在将我的实体转换为DTO,我想为所有字段设置NULL作为DTO值,这些字段是延迟加载的而不是初始化的(因为我不想一直传输所有数据)。
我试过了:
if (!(entity.getNationality() instanceof HibernateProxy))
this.setNationalityFromEntity(entity.getNationality());
但它似乎没有帮助。 欢迎任何建议!
谢谢!
答案 0 :(得分:4)
我们在实体中这样做是因为我们有布尔方法,它们以不会触发延迟加载的方式进行检查。例如,如果我们的实体有一个名为' associatedSomething'的关联实体,那么检查该关联实体是否已延迟加载的方法将是:
public boolean isAssociatedSomethingLoaded() {
if (associatedSomething instanceof HibernateProxy) {
if (((HibernateProxy)associatedSomething).getHibernateLazyInitializer().isUninitialized()) {
return false;
}
}
return (getAssociatedSomething() != null);
}
注意:在检查中不要使用getAssociatedSomething()
很重要,因为这可以确保关联的实体在检查期间不会延迟加载。
答案 1 :(得分:2)
该类始终是一个代理,无论它是否已初始化,因此如果您只检查代理实例,则每次都要排除它。延迟加载不会导致实体上的代理参考被替换为对新对象的引用,它只会填充字段。
要了解它是否实际已初始化,您需要询问它!
if (HibernateProxy.class.isInstance(entity.getNationality())) {
HibernateProxy proxy = HibernateProxy.class.cast(entity.getNationality());
if (!proxy.getHibernateLazyInitializer().isUninitialized()) {
this.setNationalityFromEntity(entity.getNationality());
}
}
答案 2 :(得分:0)
在我看来,仅能够为某个用例不可用的状态调用getter的可能性是有问题的,但这是另一回事。我建议您采用适当的DTO方法来避免意外错误。
我正是为此用例创建了Blaze-Persistence Entity Views。您实际上将JPA实体的DTO定义为接口,并将其应用于查询。它支持映射嵌套的DTO,集合等,本质上是您期望的所有内容,此外,它还将提高查询性能,因为它将生成查询,仅提取您实际为DTO所需的数据。
您的示例的实体视图如下
@EntityView(Person.class)
interface PersonDto {
String getNationality();
}
查询看起来像这样
List<PersonDto> dtos = entityViewManager.applySetting(
EntityViewSetting.create(PersonDto.class),
criteriaBuilderFactory.create(em, Person.class)
).getResultList();