2016-04-20 29 views
0

私は関係のの所有者のエンティティの子供のコレクションを取得したい。 私はこれら2つのエンティティがあります。JPAの1対多の関係 - @トランザクション - - 子供のコレクションを取得

@Entity 
@Table(name = "commande") 
public class Commande implements Serializable { 

private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@Column(name = "name") 
private String name; 

@OneToMany(mappedBy = "commande") 
@JoinColumn(name= "papa_id") 
@JsonIgnore 
private Set<Piece> pieces = new HashSet<>(); 



@Entity 
@Table(name = "piece") 
public class Piece implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(name = "ref") 
    private String ref; 

    @ManyToOne 
    private Commande commande; 

とリソースを:

@RequestMapping(value = "/papas/{id}", 
    method = RequestMethod.GET, 
    produces = MediaType.APPLICATION_JSON_VALUE) 
@Timed 
@Transactional 
public ResponseEntity<Papa> getPapa(@PathVariable Long id) { 
    log.debug("REST request to get Papa : {}", id); 
    Papa papa = papaRepository.findOne(id); 
    papa.getEnfants().size(); 
    ... 
} 

私は.size()仕事をするために@Transactionalを入れていた(そう、私は例外を持っています) 。 これは機能します。 しかし、別の方法では、私は1つのランファンエンティティを削除した場合、その後、私は再びgetPapaを呼び出す場合、私はエラーを取得しています)が(.size durint:

Unable to find com.myapp.stagiaireproject.domain.Enfant with id 3 

は、それが閉じられていないトランザクションの問題ですか?

答えて

0

初めてリポジトリを使用するすべての作業をサービスに移し、このメソッドを@Transactionalとしてマークします。 @Transactionalアノテーションをコントローラメソッドに設定するのは悪い習慣です。

デフォルトで1対多の注釈が遅延している場合、明示的に@OneToMany(mappedBy = "commande", fetch = FetchType.EAGER) に、このエンティティを取得するときにデータベースからコレクションを読み取るように設定することができます。

これは、1つのトランザクションである場合、hibernateは、第1レベルのキャッシュ(無効ではない)を使用します。すなわち、トランザクション中にPK(id)でロードするエンティティをキャッシュします。また、リポジトリを使用してすべての作業をサービスクラスに移すと、コントローラからのデータを返す前にトランザクションがコミットされ、次のリクエストでキャッシュからではなくデータベースからデータが読み込まれます。

+0

ありがとう、悪いpactriceのための権利。私のアプリケーションは、休止状態のために第2レベルのキャッシュを使用します。だから私がコードをサービスクラスに移すと、pbは終了しますか? – user1260928

+0

私はそれが問題を解決すると思います。そしてPBは何ですか? –