Я совершенно новый для спящего режима и 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; применение в памяти!
Вы решили свою проблему? – svlada