I am using @PersistenceContext to inject an instance of EntityManager in my DAO classes using Spring. I ran into this scenario -
I was trying to persist a Person entity from a PersonDAO class method like
Code:
@Transactional
public void save(Person transientInstance) {
try {
entityManager.persist(transientInstance);
entityManager.flush();
} catch (Exception e) {
throw e;
}
}
and have also configured a Hibernate Interceptor to perform audits on the Person entity. From within the interceptor I invoke AuditDAO method to fetch audit related data like
Code:
public Audit findAudit(String applicationName,
String entityName) {
log.info("Finding auditable entity with application name "
+ applicationName + "key " + entityName);
Audit entity = null;
String queryString = "from Audit model where model."
+ APPLICATION + "= :applicationValue and " + KEY
+ "= :keyValue";
try {
Query query = entityManager.createQuery(queryString);
query.setParameter("applicationValue", applicationName);
query.setParameter("keyValue", entityName);
entity = (Audit) query.getSingleResult();
} catch (Exception e) {
throw new AuditException (e);
}
if (entity != null) {
log.info("Audit found for applcation name "
+ applicationName + "entity " + entityName);
}
return entity;
}
Both these DAO classes use
Code:
@PersistenceContext
private EntityManager entityManager = null;
Upon executing the code, I ran into following issues -
1. The AuditDAO was not able to fetch records even though it existed in the db.
2. The database identity for the Person class was not maintained.
Upon adding the attribute PersistenceContextType.EXTENDED to @PersistenceContext annotation. The problem was resolved.
I read in one of the articles that -
Quote:
By default JPA provide Transaction level Persistence Context. What this means is that the Persistence Context 'lives' for the length of the transaction. If you have multiple queries using the same transaction then the same Persistence Context is used for all of those queries.
Quote:
JPA provides 'Extended Persistence Context'. This could be thought of as the Persistence Context being 'owned' by the EntityManager rather than the Transaction. In this case the same Persistence Context can be used for multiple transactions.
My questions are -
Why did I get that error?
Why was the transaction not maintained between calls across the interceptor?
Does this scenario require PersistenceContextType.EXTENDED to be specified?