My code looks like:
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final TypedQuery<ObjectTO> createQuery = criteriaBuilder.createQuery(ObjectTO.class);
...
// Logic to create search query
...
// On this line performance is very low. Takes around 200 seconds for 3000 records.
final List<ObjectTO> inhibits = createQuery.getResultList();
Generated SQL (example with reduced columns in select clause) looks like:
SELECT t1.COL1 ,
t1.COL2 ,
t1.COL3 ,
t2.COL1 ,
t2.COL2 ,
t3.COL2
FROM Table1 t1
INNER JOIN Table2 t2,
ON t1.COL1 = t2.COL1
LEFT OUTER JOIN Table3 t3
ON t1.COL1 = t3.COL1
WHERE (t1.COL2 LIKE 'test')
AND ( t1.COL3 >= SYSDATE
OR t1.COL3 = to_Date('1901.01.01 00:00:00', 'yyyy-mm-dd HH24:mi:ss') )
ORDER BY t1.COL1 ASC ,
t1.COL3 ASC ,
t2.COL2 ASC;
Same query when executed in SQL developer, takes around 0.3 seconds. Please note that same query if executed using java.sql.Statement.executeQuery(), takes around 0.4 seconds to fetch data from database. Please note that database is Oracle 11g. JDK version is 1.7.0_51.
JPA entity for Table1 looks like:
@Entity
@Table(name = "Table1")
public class Table1 implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "COL1", insertable = false, updatable = false)
private String col1;
@Column(name = "COL3", insertable = false, updatable = false)
private Timestamp col3;
@Column(name = "COL2")
private String col2;
@OneToMany(mappedBy = "col1", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
private Set<Table2> table2;
@OneToMany(mappedBy = "col1", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
private Set<Table3> table3;
...
...
}
Can you please provide me with an hint regarding where shall I start looking to improve performance in this scenario? Please let me know, if you require more information.