我正在努力编辑和更新嵌套对象,因为我一再打击这个Hibernate Lazy Loading错误。
在我的申请中:
所以我尝试编写一个方法来初始化相关对象作为一种解决方法:
@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())时的Stacktrace 被称为:
org.springframework.web.util.NestedServletException:Request 处理失败;嵌套异常是 org.hibernate.LazyInitializationException:无法初始化代理 - 没有Session org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) javax.servlet.http.HttpServlet.service(HttpServlet.java:644) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) javax.servlet.http.HttpServlet.service(HttpServlet.java:725) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
相关对象关系:
@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;
...
}
答案 0 :(得分:0)
您可能想尝试两件事。
1-添加OpenEntityManagerInViewFilter
<filter>
<filter-name>openEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2-将您的实体/表单/模型添加到会话
@Controller
@SessionAttributes("yourEntityFormModel")
public class YourController {
...
}
---------更新
发生的事情是,在一个在一个事务中运行的注释方法中,Hibernate将能够根据需要从该实体中检索关系。
所以,下面的例子工作正常。
@Transactional
public void updateEmployeesFromDepartment(int depId) {
Department dep = departmentRepository.findOne(dep.getId());
for (Employee e : dep.getEmployees()) {
// update whatever you want
}
}
但我不希望这种情况发挥作用......
public void updateEmployeesFromDepartment(int depId) {
Department dep = departmentRepository.findOne(dep.getId());
for (Employee e : dep.getEmployees()) {
// update whatever you want
}
}