2016-05-12 2 views
0

У меня есть три сущности, сессия, заказ и пользователь (часть моего проекта онлайн-билетов). В моей модели домена Order сохраняет fk как пользователя, так и сеанса. Как вы можете увидеть в моем коде:Jpa несколько @ManyToOne с Cascade


@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. Entity с аннотацией @ManyToOne является владельцем отношений. Это важно для разработчика, потому что никакие отношения не будут сохраняться, если это не сделано на стороне владельца, в этом случае это означает настройку Order.user. Однако, поскольку у вас есть cascade аннотацию о неприменении владеющей 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 упорствовать с каскадом. Однако, если вы поставите cascade аннотацию на имущем лице Order, то ваша работа становится намного проще:

// 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 будет сохраняться новый User и Order с одним вызовом. Без аннотации cascade на объекте Order, сохраняющийся Order до User предоставит вам исключение.

Ссылка: 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, у вас не будет доступа к Session.orders, когда объект станет отсоединенным, как правило, после того, как вы покинули свой сеансовый компонент или уровень обслуживания. Если вам нужен доступ к заказам, вам нужно будет получить их в запросе на выборку:

«выберите отличие s от сеанса s присоединиться выборки s.orders»

EDIT: Как было отмечено, по умолчанию этот запрос выполняет внутреннее соединение sql, которое ничего не вернет, если заказов нет. Вместо этого сделать

«выберите отличие s от сеанса сек LEFT JOIN выборка s.orders»

, так что вы всегда получите сессии, которые находятся в базе данных.

Код: Difference between FetchType LAZY and EAGER in Java Persistence API?

+0

Спасибо, только что я ищу! – ivy

+0

"выберите выделение s из сеанса s join fetch s.orders", но этот запрос вернет null, если s.orders пуст. Если у меня есть сеанс с пустыми заказами уже в базе данных, как я могу вставить в него заказ? – ivy

+0

@Ivy, смотрите обновления. –

Смежные вопросы