package org.javaee7.jpa.dynamicnamedquery.service; import static org.javaee7.jpa.dynamicnamedquery.service.QueryRepository.Queries.TEST_ENTITY_GET_ALL; import static org.javaee7.jpa.dynamicnamedquery.service.QueryRepository.Queries.TEST_ENTITY_GET_BY_VALUE; import javax.annotation.PostConstruct; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceUnit; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.ParameterExpression; import javax.persistence.criteria.Root; import org.javaee7.jpa.dynamicnamedquery.entity.TestEntity; import org.javaee7.jpa.dynamicnamedquery.entity.TestEntity_; /** * This bean's init method is called when the AS starts and dynamically creates a number of queries * and sets them as named queries on the entity manager factory. * <p> * Dynamically adding named queries is a new feature in Java EE 7. * * @author Arjan Tijms * */ @Singleton @Startup public class QueryRepository { public enum Queries { TEST_ENTITY_GET_ALL, TEST_ENTITY_GET_BY_VALUE } @PersistenceUnit private EntityManagerFactory entityManagerFactory; @PersistenceContext private EntityManager entityManager; @PostConstruct public void init() { // Stores queries that were created via the Criteria API as named queries. // This is the Criteria alternative for the feature where JPQL queries can // be placed in orm.xml files or annotations. (but note that JPQL queries can also // be added here programmatically). entityManagerFactory.addNamedQuery(TEST_ENTITY_GET_ALL.name(), buildGetAll()); entityManagerFactory.addNamedQuery(TEST_ENTITY_GET_BY_VALUE.name(), buildGetByValue()); } /** * Builds a criteria query equal to the JPQL * * <code>SELECT _testEntity FROM TestEntity _testEntity</code> * * */ private TypedQuery<TestEntity> buildGetAll() { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<TestEntity> criteriaQuery = criteriaBuilder.createQuery(TestEntity.class); Root<TestEntity> root = criteriaQuery.from(TestEntity.class); criteriaQuery.select(root); return entityManager.createQuery(criteriaQuery); } /** * Builds a criteria query equal to the JPQL * * <code>SELECT _testEntity FROM TestEntity _testEntity WHERE _testEntity.value :value</code> * * */ private TypedQuery<TestEntity> buildGetByValue() { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<TestEntity> criteriaQuery = criteriaBuilder.createQuery(TestEntity.class); Root<TestEntity> root = criteriaQuery.from(TestEntity.class); ParameterExpression<String> valueParameter = criteriaBuilder.parameter(String.class, TestEntity_.value.getName()); criteriaQuery.select(root) .where( criteriaBuilder.equal( root.get(TestEntity_.value), valueParameter) ); return entityManager.createQuery(criteriaQuery); } }