私は以下の問題を抱えています。私は@OneToMany
エンティティ(以下のコード)の遅延読み込みセットを含むJPAエンティティを持っています。ここでSpring RESTコントローラ、トランザクション内デシリアライズ
@Entity
@Table(name = "SKILL")
public class Skill {
@Id
@Column(name = "SKILL_ID")
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
private Long id;
@Column(name = "NAME")
private String name;
@ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE})
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@JsonIdentityReference(alwaysAsId=true)
private Skill parent;
@OneToMany(mappedBy="parent", cascade={CascadeType.ALL})
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@JsonIdentityReference(alwaysAsId=true)
private Set<Skill> children;
public Skill() {
}
// getters-setters ommitted
}
は春RESTコントローラからのコードです:
@RequestMapping(value = "/skill", method = RequestMethod.GET)
public ResponseEntity<List<Skill>> listAllSkills() {
Iterable<Skill> skills = skillService.getAllSkills();
return new ResponseEntity<>(Lists.newArrayList(skills), HttpStatus.OK);
}
私はこのコントローラからのエンティティを返すようにしようとするたびに、それは何が起こるか、私の知る限り理解されるように
JsonMappingException: failed to lazily initialize a collection of
role: com.juriy.arcadia.domain.Skill.children, could not initialize
proxy - no Session
をスローしますジャクソンがトランザクション境界の外でエンティティの遅延ロードを試行しているのですから、セッションが見つからないのです。私は汚いハックを追加し、レイジーロードされたトランザクション内で、手動ことになっている部品を呼び出した場合、それが動作します:
@RequestMapping(value = "/skill", method = RequestMethod.GET)
public ResponseEntity<List<Skill>> listAllSkills() {
Iterable<Skill> skills = skillService.getAllSkills();
// Hack here: load required items inside of session bounds
for (Skill s : skills) {
System.out.println("Fetched skills: "+ s.getChildren().size());
System.out.println("Fetched parent: "+ s.getParent());
}
return new ResponseEntity<>(Lists.newArrayList(skills), HttpStatus.OK);
}
質問:は怠け者の場合にはデシリアライゼーションを整理するはずな方法は何ですか - 負荷とトランザクション。トランザクションの境界内でデシリアライゼーションを行う方法はありますか?
関連する質問:コントローラレイヤーを作成するのは良い方法ではないと聞きました@Transactional
。この場合、トランザクションを設計する最良の方法は何ですか?
UPDATE:エンティティのEAGER
荷重を加えることは、(そこに実体の大きな木だとEAGER
ロードは完全にパフォーマンスを殺すツリー全体をロードします)私の場合はオプションではありません。
残念ながら、オプションはありません。依存エンティティのグラフがあり、このアプローチはあまりにも多くの負荷をかけます。私は、トランザクションの境界をデシリアライゼーションが起こっているところまで広げようとしています。 – Juriy