2014-11-13 2 views
11

Я совершенно новый для спящего режима и Spring-data-jpa. Все, что я хотел сделать, - это получить сущность и все связанные с ней объекты с использованием разбивки на страницы (существует около 40 миллионов записей). Один запрос для получения запроса как для корневых объектов, так и для всего их сопоставленного объекта/сбора = 1 запросаSpring-data-jpa eager fetch с соединением и использованием разбивки на страницы не работает

Но у меня есть проблема (n + 1): один запрос для корневых сущностей + один запрос для связанного сопоставленного объекта/коллекции каждого корневого объекта = (n + 1) запросов Это действительно влияет на производительность.

Я также хотел бы знать, правильны ли мои отображения в объектах.

Может кто-нибудь мне посоветует. Благодаря

стек Применение:

<java-version>1.7</java-version> 
<spring.framework.version>4.0.2.RELEASE</spring.framework.version> 
<hibernate-core>4.3.4.Final</hibernate-core> 
<hibernate-validator>5.1.0.Final</hibernate-validator> 
<hibernate-entitymanager>4.3.4.Final</hibernate-entitymanager> 
<spring-data-jpa>1.5.1.RELEASE</spring-data-jpa> 

У меня есть 2 классов сущностей (Customer и Order) следующим образом:

объект Customer

@Entity 
@Table(name = "view_customerOrders_to_process") 
public class Customer implements Serializable { 

private Long id; 
private List<Order> Orders; 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "customer_id", updatable = false) 
public Long getId() { 
    return id; 
} 

........ 

@NotFound(action = NotFoundAction.IGNORE) 
@OneToMany(fetch = FetchType.EAGER, mappedBy = "customer") 
//Do not cascade any changes to child entities. 
@Where(clause = "order_status = 'PENDING'") 
public List<Order> getOrders() { 
    return order; 
} 
} 

Пробовал с помощью BATCHSIZE, но по какой-то причине его не работает (такая же проблема n + 1).
//@Fetch(FetchMode.SELECT)
// @ BATCHSIZE (размер = 25)

сущность заказа:

@Table(name = "tbl_orders") 
public class Order implements Serializable { 

    private Long id; 
    private int customerId;  
    private Customer customer; 
    private OrderType orderType; 

    .......... 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "order_id", updatable = false) 
    public Long getId() { 
     return this.id; 
    } 

    @OneToOne 
    @NotFound(action = NotFoundAction.IGNORE) 
    @JoinColumn(name = "order_type", nullable = true, unique = false, updatable = false) 
    public OrderType getOrderType() { 
     return this.orderType; 
    } 

    @NotFound(action = NotFoundAction.IGNORE) 
    @ManyToOne(fetch = FetchType.LAZY, optional = true, targetEntity = Customer.class) 
    @Fetch(FetchMode.JOIN) 
    @JoinColumns({ 
     @JoinColumn(updatable = false, insertable = false, 
      name="customer_id", referencedColumnName = "customer_id", nullable=false), 
     . . . . . 
    }) 
    public Customer getCustomer() { 
     return customer; 
    } 
} 

Класс обслуживания:

@Service 
public class MetsGeneratorService { 

    . . . 

    @Autowired 
    private CustomerRepository customerRepository; 

    public List<Customer> run() { 
     PageRequest pageRequest = new PageRequest(0, batchSize);   
     List<Customer> customers = customerRepository.findOrdersUnprocessed(pageRequest); 
     return customers; 
    } 

    . . . 
} 

Repository:

public interface CustomerRepository extends JpaRepository<Customer, Long> { 

    @Query("SELECT e FROM Customer e") 
    List<Customer> findOrdersUnprocessed(Pageable pageable); 

    //Tried using the below one which seems to eliminate paging 
    //and understandably getting out of memory. 
    //@Query(value = "SELECT e FROM Customer e left join fetch e.orders")  

} 

Пробный переход на

@Query(value = "SELECT e FROM Customer e left join fetch e.orders", 
     countQuery = "select count(e) from Customer e") 
List<Customer> findOrdersUnprocessed(Pageable pageable); 

если вы видите журнал, который обрабатывает, делая «select *» вместо пейджинга.

Сообщение журнала WARN org.hibernate.hql.internal.ast.QueryTranslatorImpl - HHH000104: firstResult/maxРезультаты, указанные с помощью коллекции fetch; применение в памяти!

+0

Вы решили свою проблему? – svlada

ответ

2

Вы можете использовать

@Fetch(FetchMode.SUBSELECT) 

удалить (п + 1) проблема запроса.

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