2015-12-24 2 views
1

Я создал следующие объекты для управления упорной корзины:Регистрация забирающего @ManyToOne вложенного внутрь @OneToMany

ShoppingCart.java:

@Entity 
public class ShoppingCart { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @PrivateOwned 
    @OneToMany(mappedBy = "cart", cascade = CascadeType.ALL) 
    @OrderBy("creationTimestamp") 
    private List<ShoppingCartItem> items; 

    public ShoppingCart() {} 

    // Getters and setters... 
} 

ShoppingCartItem.java:

@Entity 
@IdClass(ShoppingCartItemId.class) 
public class ShoppingCartItem { 
    @Id 
    @ManyToOne 
    private Item item; 

    @Id 
    @ManyToOne 
    private ShoppingCart cart; 

    private int quantity; 

    @Column(precision = 17, scale = 2) 
    private BigDecimal price; 

    @Temporal(TemporalType.TIMESTAMP) 
    private Date creationTimestamp; 

    protected ShoppingCartItem() {} 

    @PrePersist 
    protected void prePersist() { 
     creationTimestamp = new Date(); 
    } 

    public ShoppingCartItem(ShoppingCart cart, Item item, int quantity) { 
     this.cart = cart; 
     this.item = item; 
     this.quantity = quantity; 
     this.price = item.getPrice(); 
    } 

    // Getters and setters... 
} 

Item.java:

@Entity 
public class Item { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @ManyToOne 
    private Brand brand; 

    private String model; 
    private String variant; 
    private String description; 

    @Column(precision = 17, scale = 2) 
    private BigDecimal price; 

    private int availability; 

    protected Item() {} 

    // Constructors, getters and setters... 
} 

Когда я оформить следующий JPQL запрос:

SELECT c FROM ShoppingCart c JOIN FETCH c.items WHERE c.id = :id 

Я заметил, что все ShoppingCartItem s в том же ShoppingCart извлекаются, как ожидается, в одном запросе, но @ManyToOne private Item item; поле не в объединении и отдельный запрос для каждого ShoppingCartItem выдается для получения этого поля при доступе .

Использование EclipseLink, есть ли способ иметь также соединение Item s, когда соединение/пакетное извлечение ShoppingCartItem s? Как изменить запрос и/или код?

ответ

0

Хотя left join fetch s с псевдонимами, кажется, игнорируются, я нашел этот запрос намек, что сделать работу:

Query query = entityManager.createQuery("SELECT c FROM ShoppingCart c WHERE c.id = :id"); 
query.setHint("eclipselink.left-join-fetch", "c.items.item.brand"); 

Это, вероятно, лучше, чем аннотаций подход, как это может быть указано в одном запросе ,


UPDATE

Использование этого намека сломал @OrderBy("creationTimestamp") так ShoppingCartItem s не возвращаются в порядке, они были вставлены больше. Вероятно, это связано с ошибкой в ​​EclipseLink, но я думаю, что на самом деле это не так больно, так как на самом деле мне нужно иметь упорядоченные элементы, только показывая корзину пользователю, а не, например, когда пользователь входит в систему и элементы в анонимной корзине необходимо передать в корзину пользователя.

1

Если вы используете EclipseLink, вы можете взглянуть на аннотации @BatchFetch и @JoinFetch.

+0

, но тогда при использовании обработки JPA и JPA было бы неразумно делать это (и выбрасывать переносимость) –

+1

Да, это правда, но вопрос содержал термин «Использование EclipseLink, есть ли способ» и использование аннотации намного проще и менее подвержены ошибкам, чем использование строковых JPQL или запросов критериев. Возможно, используются и другие проприетарные функции EclipseLink. –