Hibernate @OneToMany calls several select statements

I am working on a Hibernate issue that includes 2 separate Entity beans, defined separately in their classes:

  • Score
  • StoreServer

Please note that there will be more than one StoreServer in the Store - hence the use of the @OneToMany annotation. See Code Snippets as follows:

Store:

@Entity
@Table(name="Store")
public class Store implements Serializable {
/**
* Serializable class - generated UID
*/
private static final long serialVersionUID = 5644190852867691168L;

@Id
@Column(name="STORE_NO", nullable=false)
private int storeNumber;

@Column(name="STORE_NAME", nullable=false)
private String storeName;

@Column(name="STORE_PHONE", nullable=false)
private String storePhone;

//other Store fields...

@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name="STORE_NO", insertable=false, updatable=false)
private List<StoreServer> storeServers = new ArrayList<StoreServer>();

//getters and setters

StoreServer:

@Entity
@Table(name="Store_Server")
public class StoreServer implements Serializable {
/**
* Serializable class - generated UID
*/
private static final long serialVersionUID = -5410564578856243437L;

@Id
private StoreServerPK storeServerPK;

@Column(name="IP_ADDRESS", nullable=true)
private String ipAddress;

//other StoreServer fields...getters and setters

Since StoreServer has a composite primary key, here StoreServerPK:

@Embeddable
public class StoreServerPK implements Serializable {
/**
* Serializable class - generated UID
*/
private static final long serialVersionUID = -1401889029390423604L;

@Column(name="STORE_NO", nullable=false)
protected int storeNumber;

@Column(name="SERVER_NO", nullable=false)
protected String serverNumber;

//getters and setters

I'm currently getting the right results, but performance is unacceptably slower. I turned on logging in Hibernate, and I see that for each Storage, a separate SELECT query is created to retrieve the associated StoreServer entries.

SELECT ( 200 ). SELECT StoreServer. : Hibernate ( )?

, , Hibernate , JOIN?

+4
1

N + 1

, - , API , Root.fetch:

CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Store> cq = qb.createQuery(Store.class);

Root<Store> root = cq.from(Store.class);
root.fetch(App_.storeServers, JoinType.LEFT);

cq.select(root);

return em.createQuery(cq).getResultList();

HQL, fetch:

select distinct st from Store st left join fetch st.storeServers

, , Hibernate , , H2 JDBC Sniffer

+1

All Articles