由于我不断遇到的 Hibernate Lazy Loading 错误,我正在努力编辑和更新嵌套对象。
在我的应用程序中:
- 我将图像集绑定到产品。
- 我使用格式化程序转换图像集以在选择框中使用,因此用户可以选择图像集。
- 如果表单成功,对象绑定并且关系正确保存,则效果很好。
- 但是,如果验证失败,每当 UI 层尝试访问嵌套对象值时,我都会收到可怕的延迟初始化/无会话错误!
所以我尝试编写一个方法来初始化相关对象作为解决方法:
@Transactional
public void initObject(Variant variant) {
Hibernate.initialize(variant.getOption1());
Hibernate.initialize(variant.getOption2());
Hibernate.initialize(variant.getOption3());
Hibernate.initialize(variant.getImageSet());
}
该方法中的前 3 行有效(这些是单向的一对一),但第四行无效(这是多对一),它仍然表示没有代理。
我也尝试过制作所有 Eager fetch 类型。
这些都不起作用。
问题可能是我正在创建父对象,当出现验证错误时它不会保存到数据库中,但是无论出于何种原因,嵌套对象都是惰性代理对象,无论获取类型如何(请参阅下面的格式化程序) .
我怎样才能解决这个问题?
这是格式化程序组件:
@Component
public class ImageSetFormatter implements Formatter<ProductImageSet> {
private static Logger logger = LogManager.getLogger(VariantController.class.getName());
@Autowired
private ProductImageService imageService;
@Override
public ProductImageSet parse(String s, Locale locale) throws ParseException {
logger.entry();
Long imageSetId = Long.valueOf(s);
logger.exit();
return imageService.getImageSet(imageSetId);
}
@Override
public String print(ProductImageSet productImageSet, Locale locale) {
logger.entry();
logger.exit();
return Long.toString(productImageSet.getId());
}
}
调用 Hibernate.initialize(variant.getImageSet()) 行时的堆栈跟踪:
org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是 org.hibernate.LazyInitializationException: 无法初始化代理 - 没有会话 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:第863章725) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) org.springframework.web.filter.HiddenHttpMethodFilter。
相关对象关系:
@Entity
@Table(name="variants")
@EntityListeners({AuditingEntityListener.class})
public class Variant extends AbstractAuditable<Customer, Long> {
@OneToOne
private VariantOptionValue option1;
@OneToOne
private VariantOptionValue option2;
@OneToOne
private VariantOptionValue option3;
...
@ManyToOne
@JoinColumn(name="image_set_id")
@LazyCollection(LazyCollectionOption.FALSE )
private ProductImageSet imageSet;
}
@Entity
@Table(name="product_image_set")
@EntityListeners({AuditingEntityListener.class})
public class ProductImageSet extends AbstractAuditable<Customer, Long> {
public ProductImageSet(String label)
{
this.label = label;
}
public ProductImageSet(){
}
@Basic
@Column(length = 50, nullable = false)
private String label;
@OneToMany(mappedBy = "imageSet", fetch = FetchType.EAGER)
private List<ProductImage> images;
@OneToMany(mappedBy = "imageSet", fetch = FetchType.EAGER)
private List<Variant> variants;
private int sequence;
@ManyToOne
@JoinColumn(name = "product_id")
private Product product;
...
}