Hibernate merge выполняет 11000 отборов перед обновлением - PullRequest
0 голосов
/ 04 сентября 2018

Я работаю над проектом JSF / JPA с базой данных Sakila на MySQL с помощью Hibernate. Когда я хочу объединить объект клиента в БД, это занимает 20 секунд. Я предполагаю, что это связано с отображением моего класса сущностей, но я не могу понять, что я сделал неправильно. Вот мой класс клиентов:

@Entity
@Table(name = "customer")
public class Customer implements Serializable, IEntity {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "customer_id")
private Short customerId;

@Basic(optional = false)
@Column(name = "first_name")
private String firstName;

@Basic(optional = false)
@Column(name = "last_name")
private String lastName;

@Column(name = "email")
private String email;

@Basic(optional = false)
@Column(name = "active")
private boolean active;

@Basic(optional = false)
@Column(name = "create_date")
@Temporal(TemporalType.TIMESTAMP)
private Date createDate;

@Basic(optional = false)
@Column(name = "last_update")
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdate;

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customerId")
private List<Rental> rentalList;

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customerId")
private List<Payment> paymentList;

@JoinColumn(name = "address_id", referencedColumnName = "address_id")
@ManyToOne(optional = false)
private Address addressId;

@JoinColumn(name = "store_id", referencedColumnName = "store_id")
@ManyToOne(optional = false)
private Store storeId;

//Constructor 

//getter_setter
}

И в моем CustomerService EJB я вызываю функцию слияния:

@Named
@Stateless
public class CustomerService {

@PersistenceContext(name = "sakila")
EntityManager em;

public String merge(IEntity entity) {
    try {
        em.merge(entity);
        return "success";
    }catch(Exception e){
        return "failure";
        }
    }
}

В журнале видно, что hibernate выполняет 11037 операторов выбора, как этот

 select
    paymentlis0_.customer_id as customer5_11_0_,
    paymentlis0_.payment_id as payment_1_11_0_,
    paymentlis0_.payment_id as payment_1_11_1_,
    paymentlis0_.amount as amount2_11_1_,
    paymentlis0_.customer_id as customer5_11_1_,
    paymentlis0_.last_update as last_upd3_11_1_,
    paymentlis0_.payment_date as payment_4_11_1_,
    paymentlis0_.rental_id as rental_i6_11_1_,
    paymentlis0_.staff_id as staff_id7_11_1_,
    rental1_.rental_id as rental_i1_12_2_,
    rental1_.customer_id as customer5_12_2_,
    rental1_.inventory_id as inventor6_12_2_,
    rental1_.last_update as last_upd2_12_2_,
    rental1_.rental_date as rental_d3_12_2_,
    rental1_.return_date as return_d4_12_2_,
    rental1_.staff_id as staff_id7_12_2_,
    customer2_.customer_id as customer1_5_3_,
    customer2_.active as active2_5_3_,
    customer2_.address_id as address_8_5_3_,
    customer2_.create_date as create_d3_5_3_,
    customer2_.email as email4_5_3_,
    customer2_.first_name as first_na5_5_3_,
    customer2_.last_name as last_nam6_5_3_,
    customer2_.last_update as last_upd7_5_3_,
    customer2_.store_id as store_id9_5_3_,
    inventory3_.inventory_id as inventor1_9_4_,
    inventory3_.film_id as film_id3_9_4_,
    inventory3_.last_update as last_upd2_9_4_,
    inventory3_.store_id as store_id4_9_4_,
    staff4_.staff_id as staff_id1_13_5_,
    staff4_.active as active2_13_5_,
    staff4_.address_id as address10_13_5_,
    staff4_.email as email3_13_5_,
    staff4_.first_name as first_na4_13_5_,
    staff4_.last_name as last_nam5_13_5_,
    staff4_.last_update as last_upd6_13_5_,
    staff4_.password as password7_13_5_,
    staff4_.picture as picture8_13_5_,
    staff4_.store_id as store_i11_13_5_,
    staff4_.username as username9_13_5_,
    staff5_.staff_id as staff_id1_13_6_,
    staff5_.active as active2_13_6_,
    staff5_.address_id as address10_13_6_,
    staff5_.email as email3_13_6_,
    staff5_.first_name as first_na4_13_6_,
    staff5_.last_name as last_nam5_13_6_,
    staff5_.last_update as last_upd6_13_6_,
    staff5_.password as password7_13_6_,
    staff5_.picture as picture8_13_6_,
    staff5_.store_id as store_i11_13_6_,
    staff5_.username as username9_13_6_,
    address6_.address_id as address_1_1_7_,
    address6_.address as address2_1_7_,
    address6_.address2 as address3_1_7_,
    address6_.city_id as city_id8_1_7_,
    address6_.district as district4_1_7_,
    address6_.last_update as last_upd5_1_7_,
    address6_.phone as phone6_1_7_,
    address6_.postal_code as postal_c7_1_7_,
    store7_.store_id as store_id1_14_8_,
    store7_.address_id as address_3_14_8_,
    store7_.last_update as last_upd2_14_8_,
    store7_.manager_staff_id as manager_4_14_8_,
    store8_.store_id as store_id1_14_9_,
    store8_.address_id as address_3_14_9_,
    store8_.last_update as last_upd2_14_9_,
    store8_.manager_staff_id as manager_4_14_9_ 
from
    payment paymentlis0_ 
left outer join
    rental rental1_ 
        on paymentlis0_.rental_id=rental1_.rental_id 
left outer join
    customer customer2_ 
        on rental1_.customer_id=customer2_.customer_id 
left outer join
    inventory inventory3_ 
        on rental1_.inventory_id=inventory3_.inventory_id 
left outer join
    staff staff4_ 
        on rental1_.staff_id=staff4_.staff_id 
inner join
    staff staff5_ 
        on paymentlis0_.staff_id=staff5_.staff_id 
inner join
    address address6_ 
        on staff5_.address_id=address6_.address_id 
inner join
    store store7_ 
        on staff5_.store_id=store7_.store_id 
left outer join
    store store8_ 
        on staff5_.staff_id=store8_.manager_staff_id 
where
    paymentlis0_.customer_id=?

Требуется 20 секунд, прежде чем Hibernate наконец отправит запрос на обновление

Information:   Hibernate: 
update
    customer 
set
    active=?,
    address_id=?,
    create_date=?,
    email=?,
    first_name=?,
    last_name=?,
    last_update=?,
    store_id=? 
where
    customer_id=?

Я предполагаю, что мое сопоставление неверно, и клиент настроен для ленивой загрузки. Кто-то может указать на мою ошибку?

1 Ответ

0 голосов
/ 04 сентября 2018

Очевидно, что для слияния реализация JPA (здесь Hibernate) должна знать, есть ли какие-либо изменения, сделанные в отсоединенных (или ленивых, еще не извлеченных) объектах или нет, таким образом, она проверяет свое состояние с помощью SELECT. Поскольку вы являетесь каскадом (с CascadeType.ALL), вы объединяете все связанные сущности - весь граф обновляется.

Либо не каскадные слияния, либо принудительное слияние используют обновление JPQL (или CriteriAPI), если вам нужно только обновить родительскую сущность, не считая ее дочерние.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...