この Hibernate Lazy Loading エラーが何度も発生するため、ネストされたオブジェクトの編集と更新に苦労しています。
私のアプリケーションでは:
- イメージ セットを製品にバインドします。
- フォーマッタを使用して、選択ボックスで使用するイメージセットを変換したので、ユーザーはイメージ セットを選択できます。
- フォームが成功し、オブジェクトがバインドされ、関係が正しく保存されれば、うまく機能します。
- しかし、検証に失敗すると、UI レイヤーがネストされたオブジェクトの値にアクセスしようとするたびに、恐ろしい Lazy Initialization/No Session エラーが発生します。
そこで、回避策として関連オブジェクトを初期化するメソッドを作成しようとしました。
@Transactional
public void initObject(Variant variant) {
Hibernate.initialize(variant.getOption1());
Hibernate.initialize(variant.getOption2());
Hibernate.initialize(variant.getOption3());
Hibernate.initialize(variant.getImageSet());
}
そのメソッドの最初の 3 行は機能しますが (これらは単方向の 1 対 1 です)、4 行目は機能しません (これは多対 1 です)。
また、すべてを 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) 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.
関連するオブジェクトの関係:
@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;
...
}