2016-05-12 9 views
0

私は3つのエンティティ、セッション、オーダー、ユーザー(私のオンライン映画チケットプロジェクトの一部)を持っています。私のドメインモデルでは、OrderはUserとSessionの両方のfkを保持します。あなたは私のコードで見ることができるように:Jpa複数の@ManyToOneとカスケード


@Table(name="Orders") 
@Entity 

public class Order { 
    @ManyToOne 
    @JoinColumn(nullable = false) 
    private User user; 

    @ManyToOne 
    private Session session; 
    ... 
} 



@Entity 
@Table(name="Session") 

public class Session { 
    @OneToMany(fetch=FetchType.LAZY, 
       cascade = CascadeType.ALL, 
       mappedBy = "session") 
    private List<Order> orders = new ArrayList<Order>(); 
    ... 
} 



@Table(name="User") 
@Entity 

public class User { 
    @OneToMany(cascade = { CascadeType.PERSIST, 
          CascadeType.MERGE, 
          CascadeType.REMOVE }, 
       mappedBy = "user") 
    private @Getter Set<Order> orders = new HashSet<>(); 
    ... 
} 

私の質問があり、私はセッションとユーザーの両方にCascadeType.ALLは使用できますか? セッションとユーザーの両方で注文を更新すると、競合する可能性がありますか?


ご覧のとおり、fetchType.Lazyを使用して、セッションとユーザーの両方の注文が最新であることを保証できますか?

答えて

0

質問1:良い質問ですが、回答するにはowningエンティティの概念を理解する必要があります。 @ManyToOne注釈付きのEntityは、関係の所有者です。これは、所有側で行われていない限り、永続化される関係がないため、開発者にとって重要です。この場合は、Order.userを設定することを意味します。

// create Order 
Order order = new Order(); 
// create User and Set of orders 
User user = new User(); 
Set<Order> userOrders = new HashSet<Order>(); 
user.setOrders(userOrders); 
userOrders.add(order); 
// and set Order.user 
order.setUser(user); 
// persist with cascade 
em.persist(user); 

お知らせご注文のセットを作成しなければならないだけでなく、設定Order.user:あなたは非所有Usercascade注釈を持っているのでしかし、あなたはカスケード機能を使用するために余分な作業をしなければなりませんカスケードで持続する。しかし、あなたが所有しているエンティティOrdercascade注釈を入れた場合、その後、あなたの仕事は非常に簡単になる:

// create User 
User user = new User(); 
// create Order 
Order order = new Order(); 
// and set Order.user 
order.setUser(user); 
// persist with cascade 
em.persist(order); 

が今だけorderを永続化することは、1回の呼び出しで新しいUserOrderを持続します。 Orderエンティティのcascade注釈がない場合、OrderUserの前に残すと例外が発生します。

参考文献:What is the “owning side” in an ORM mapping?In a bidirectional JPA OneToMany/ManyToOne association, what is meant by “the inverse side of the association”?

質問2:FetchType.LAZYはあなたが特定のクエリによって子を取得しなければならないことを意味、私はあなたの質問を理解していれば、答えはノーである、それは何かを保証するものではありません。 FetchType.LAZYの場合、Sessionを取得すると、エンティティがデタッチされたときに、通常はセッションBeanまたはサービスレイヤから離れると、Session.ordersにアクセスすることはできなくなります。あなたが発注へのアクセスが必要な場合は、選択クエリでそれらを取得する必要があります。

EDIT「s.ordersをフェッチ参加セッションsからの個別の選択」:述べたように、デフォルトでこの問合せはSQLの内部結合を実行し、順序がない場合は何も戻されません。その代わり、

を行うあなたは常にデータベースにあるセッションを取得するよう

「セッションの左から明確なSを選択するには、s.ordersをフェッチ参加します」。

参考:Difference between FetchType LAZY and EAGER in Java Persistence API?

+0

ありがとう、ちょうど私が探しているもの! – ivy

+0

「セッションsから別名を選択してs.ordersをフェッチする」が、このクエリはs.ordersが空の場合はnullを返します。空のオーダーのセッションが既にデータベースにある場合、どのようにオーダーを挿入できますか? – ivy

+0

@Ivy、アップデートをご覧ください。 –