Using JPA (standard):
- The default @OneToMany relation is lazy-load (i.e. the default value for fetch = FetchType.LAZY). But calling
Entity.getCollection().size() will result in lazy loading to get the entire child collection - so yes, it will be pretty slow if you don't need to work with all / most of the elements. Note: for all (normal) JPA implementations, this will NOT issue 30,000 separate requests - it issues a single request that returns 30,000 rows in the result set. - If you need most elements or you want to cache the change in
@OneToMany(fetch=FetchType.EAGER) on @OneToMany(fetch=FetchType.EAGER) - The general way to get data statistics without retrieving each individual object is to simply use JPQL through
EntityManager.getQuery()/getTypedQuery()/getNamedQuery() (or even SQL through getNativeQUery() ). It is quite simple and highly efficient:
int empSize = em.createQuery("SELECT SIZE(d.employees) FROM Department d") .getSingleResult();
OR ALTERNATIVELY // Pre-compiled query placed against entity class for highest performance @NamedQueries({ @NamedQuery(name="Department.EmployeeSize", query="SELECT SIZE(d.employees) FROM Department"), ... // other named queries }) @Entity public class Department { ... } // Then to use the query: int empSize = em.createNamedQuery("Department.EmployeeSize", Integer.class) .getSingleResult();
Map propertiesMap = new HashMap(); // Valid values are ALL, NONE, ENABLE_SELECTIVE, DISABLE_SELECTIVE propertiesMap.add("javax.persistence.sharedCache.mode", "ENABLE_SELECTIVE"); EntityManagerFactory = Persistence.createEntityManagerFactory("myPUName", propertiesMap);
ALTERNATIVELY use persistence.xml: <persistence-unit name="EmployeeService"> ... <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> </persistence-unit>
Then note which objects should be automatically cached in the level 2 cache:
@Cacheable(true) @Entity public class Employee { ... }
- You can also configure dynamic caching as part of a specific request.
Using a proprietary approach (for example, Hibernate "Extra-Lazy"):
- Same performance as just issuing a JPQL / SQL query
- Save a couple lines of code (@ org.hibernate.annotations.LazyCollection (EXTRA) annotation v @NamedQuery annotations and execution)
- Non-standard - JPA developers will not know about it
- Not portable - can only be used with this provider. There is an industry trend towards standard JPA, from proprietary features. There are many different JPA implementations.
source share