Access current bound DataAccessUnit (bound by domain or login):
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager();
Access a specified DataAccessUnit:
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager(dataAccessUnit);
Access the system DataAccessUnit:
BackingBeanContext context = BackingBeanContext.getInstance();
DataAccessUnit systemDataAccessUnit = context.getSystemDataAccessUnit();
PersistenceEntityManager peManager = context.getPersistenceEntityManager(systemDataAccessUnit);
Access the DataAccessUnit associated with a Component such as ContainerBean,
BackingBean, EntityProperty, MenuNode, etc.
PersistenceEntityManager peManager = component.getPersistenceEntityManager();
For example, retrieve all full-time employees
PersistenceEntityManager peManager = backingBean.getPersistenceEntityManager();
QueryCriteria queryCriteria = new QueryCriteria(Employee.class,
new CriteriaElement[]{DetachedCriteria.eq("type", Employee.Type.FULL_TIME)});
List<Employee> employees = peManager.getEntityList(queryCriteria, null, null);
To access JPA EntityManager:
PersistenceEntityManager peManager = backingBean.getPersistenceEntityManager();
EntityMangaer entityManager = peManager.getEntityManager();
Pass query hints to PersistenceEntityManager:
QueryHints queryHints = new QueryHints();
queryHints.instanceHint(null);
PersistenceEntityManager peManager = backingBean.getPersistenceEntityManager(
transactionRequired, queryHints);
By default, instanceType DataAccessUnit will search entities of all instances and
entities not associated with any instances. Setting instanceHint to null will limit
query scope to those entities not associated with any instances.
Transaction is required for creating/updating/deleting entities in persistence.
Pass query hints to query.
PersistenceEntityManager peManager = backingBean.getPersistenceEntityManager();
QueryCriteria queryCriteria = new QueryCriteria(Employee.class,
new CriteriaElement[]{DetachedCriteria.eq("type", Employee.Type.FULL_TIME)});
queryCriteria.distinct(true);
queryCriteria.setHint(Constants.DISTINCT_MODE, "db");
List<Employee> employees = peManager.getEntityList(queryCriteria, 0, 10);
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager(dataAccessUnit, true);
Employee employee = new Employee(nid, name, type, hiredDate);
peManager.persistEntity(employee);
// change and save it
employee.setType(Employee.Type.FULL_TIME);
employee = peManager.mergeEntity(employee);
// delete it
peManager.removeEntity(employee);
Entities are detached from persistence context at the end of each transaction.
Transaction listeners can be registered with current active transaction, and they will be called when the transaction is committed or rolled back. For example,
TransactionListener listener = new DefaultTransactionListener() {
@Override
public PageNavigation committed(PhaseId phaseId) throws SystemException {
// do something
return null;
}
@Override
public PageNavigation rolledback(PhaseId phaseId) throws SystemException {
// do something
return null;
}
};
TransactionPhaseListener.addTransactionListener(listener);
To explicitly start a transaction for a DataAccessUnit, e.g., in a Servlet
UserTransactionWrapper userTransactionWrapper = new UserTransactionWrapper(dataAccessUnit);
userTransactionWrapper.begin(false);
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager(dataAccessUnit, true);
// create/update/delete entities
userTransactionWrapper.commit();
For RESOURCE_LOCAL, a default JPAEntityManagerAccessor has been registered. For JTA, a JPAEntityManagerAccessor impl for JTA with PersistenceContext injections needs to be registered. For example,
public class JTAEntityManagerAccessor implements JPAEntityManagerAccessor {
@PersistenceContext(unitName="system")
private EntityManager systemEntityManager;
@PersistenceContext(unitName="persistenceUnit_1")
private EntityManager puOneEntityManager;
@Override
public EntityManager getEntityManager(QueryDescriptor queryDescriptor) {
String persistenceUnit = queryDescriptor.getPersistenceUnit();
if (persistenceUnit.equals("system"))
return systemEntityManager;
if (persistenceUnit.equals("persistenceUnit_1"))
return puOneEntityManager;
throw new IllegalArgumentException("EntityManager not found for persistence unit: " + persistenceUnit);
}
@Override
public void clearEntityManagers(boolean allPersistenceUnits) {
// EntityManager type is transaction, cleared at the end of each transaction.
// so no need to clear(detach) entities.
}
}
In a Module implementation class, register the JTAEntityManagerAccessor.
@Override
public void registerPersistenceEntityManagers() {
JTAEntityManagerAccessor jtaEntityManagerAccessor = ; // get the instance
PersistenceEntityManagerRegistry.register(true, jtaEntityManagerAccessor);
}
public InventoryManager extends PersistenceEntityManager {
public Integer getStockQuantity(Merchandise merchandise);
}
The implementation class extends PersistenceEntityManagerBean. For example,
public InventoryManagerBean extends PersistenceEntityManagerBean implements InventoryManager {
@Override
public Integer getStockQuantity(Merchandise merchandise) {
...
}
}
Register the extended PersistenceEntityManager in module implementation:
@Override
public void registerPersistenceEntityManagers() {
PersistenceEntityManagerRegistry.register(InventoryManager.class, InventoryManagerBean.class);
}
An InventoryManager instance can be obtained in the following way:
BackingBeanContext context = BackingBeanContext.getInstance();
// access a DataAccessUnit
InventoryManager inventoryManager = context.getPersistenceEntityManager(InventoryManager.class, dataAccessUnit);
// access a DataAccessUnit with query hints, transaction required
InventoryManager inventoryManager = context.getPersistenceEntityManager(InventoryManager.class, dataAccessUnit,
transactionRequired, queryHints);
<non-jta-data-source>jdbc/data_source_1</non-jta-data-source> or <jta-data-source>jdbc/data_source_1</jta-data-source>For installer to configure data sources for Tomcat (e.g., install tomcat for test automation), create context.xml under ${root_project_dir}/install/installer/tomcat/.
<Context> <!-- data sources: The connection URL variable for an instance type is @JDBC_URL.instanceTypeId@, e.g., variable @JDBC_URL.system@ for system instance, variable @JDBC_URL.xyz@ for instance type "xyz". All variables will be resolved by installer. --> <Resource name="jdbc/data_source_1" auth="Container" type="javax.sql.DataSource" driverClassName="@JDBC_DRIVER@" url="@JDBC_URL.system@" username="@JDBC_USER@" password="@JDBC_PASSWORD@" maxActive="50" maxIdle="10"/> <Resource name="jdbc/data_source_2" auth="Container" type="javax.sql.DataSource" driverClassName="@JDBC_DRIVER@" url="@JDBC_URL.xyz@" username="@JDBC_USER@" password="@JDBC_PASSWORD@" maxActive="200" maxIdle="20"/> </Context>Add the following at the beginning of the build.gradle of root project:
ext {
// use jdbc connection pool
set("jdbc.connectionPool", "true")
}
When running "gradlew install", the following property will be added to the generated
answer.properties file.
jdbc.connectionPool = true
and Tomcat will be installed with the context.xml (variables replaced).
select nid and name of employees hired before a certain date and return the first 100 results.
String query = "select nid, name from Employee where hiredDate<:hiredDate";
Map<String, Object> parameterMap = new Hash<String, Object>();
parameterMap.put("hiredDate", aDate);
QueryCriteria queryCriteria = new QueryCriteria(Object[].class,
new DataDescriptor(Object[].class, true, false),
query, QueryType.JPQL, parameterMap);
List<Object[]> results = peManager.searchResults(queryCriteria, 0, 100);
for (int i=0; i<results.size(); i++) {
Object[] row = results[i];
...
}
Or execute query without QueryCriteria:
String query = "select nid,name from Employee where hiredDate<:hiredDate";
List results = peManager.executeQueryResultList(query, QueryType.JPQL, new Object[]{"hiredDate", aDate});
Example 2: JPQL update
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager();
String query = "update Employee set type=:type where hiredDate<:hiredDate";
peManager.executeUpdate(query, QueryType.JPQL, new Object[]{"type", Employee.Type.FULL_TIME, "hiredDate", aDate});
Example 3: Pagination
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager();
CriteriaElement[] pqeList = new CriteriaElement[]{
DetachedCriteria.eq("type", Employee.Type.FULL_TIME),
DetachedCriteria.desc("hiredDate")};
QueryCriteria<Employee, Employee> queryCriteria =
new QueryCriteria<Employee, Employee>(Employee.class, pqeList);
// pagination
List<Employee> employees = peManager.getEntityList(queryCriteria, 0, 20);
List<Employee> employees = peManager.getEntityList(queryCriteria, 20, 20);
// row count
int numberOfEmployees = peManager.getRowCount(queryCriteria);
Example 4: Create/update/delete
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager();
// create
Employee employee = new Employee(...);
peManager.persistEntity(employee);
// update
employee.setName("NewName");
employee = peManager.mergeEntity(employee);
// delete
peManager.removeEntity(employee);
Batch update: change all the part-time employees hired before a certain date
to full-time employees.
Data aDate = ;
peManager.updateProperties(Employee.class, new CriteriaElement[]{
DetachedCriteria.lt("hiredDate", aDate),
DetachedCriteria.eq("type", Employee.Type.PART_TIME)},
new Object[]{"type", Employee.Type.FULL_TIME});
Batch delete: delete all the expense claims that are older than a certain date.
Data aDate = ;
peManager.deleteEntities(ExpenseClaim.class, new CriteriaElement[]{
DetachedCriteria.lt("date", aDate)});
Example 5: Lock entity
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager();
Employee employee = ;
// reload with write lock
employee = peManager.lock(employee, true, LockModeType.WRITE);
// retrieve entity with write lock
Employee employee = peManager.lock(Employee.class, 100, LockModeType.WRITE);
Example 6: Detach entities/clear L2 cache
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager();
Collection<Employee> employees = ;
// detach employees, and clear L2 cache
peManager.detachEntities(employees, true);
Example 7: Check whether an entity/property is loaded
BackingBeanContext context = BackingBeanContext.getInstance();
PersistenceEntityManager peManager = context.getPersistenceEntityManager();
// check entity
ExpenseClaim expenseClaim = ;
boolean loaded = peManager.isLoaded(expenseClaim);
// check property
boolean loaded = peManager.isLoaded(expenseClaim, "expenseClaimItems");