Enterprise Java Development@TOPIC@
Author author = new Author();
author.setFirstName("dr");
author.setLastName("seuss");
author.setSubject("children");
author.setPublishDate(new Date());
logger.debug("creating author: {}", author);
em.persist(author);
logger.debug("created author: {}", author);
-creating author:ejava.examples.daoex.bo.Author@17e7691, id=0, fn=dr, ln=seuss, subject=children, pdate=Sun Sep 16 10:14:32 EDT 2012, version=0 -created author:ejava.examples.daoex.bo.Author@17e7691, id=50, fn=dr, ln=seuss, subject=children, pdate=Sun Sep 16 10:14:32 EDT 2012, version=0
Inserts entity into database
Actual insert time depends on transaction active and FlushMode
Extended Persistence Context - queues insert until transaction active
Transaction-Scoped Persistence Context - always has transaction active
Flush occurs automatically prior to or during commit()
Flush can be forced with manual em.flush()
call
New or removed entity enters managed state
All further changes are watched and will update database
logger.debug("em.contains(author)={}", em.contains(author));
em.persist(author);
logger.debug("created author: {}", author);
logger.debug("em.contains(author)={}", em.contains(author));
-em.contains(author)=false
-created author:...
-em.contains(author)=true
Existing entity is ignored
Cascades will still occur for CascadeType.PERSIST and ALL relationships
em.persist(author);
...
em.persist(author);
It is quite legal to call persist() with an already managed entity. This is how one can get cascade actions to be applied to new relationships formed after the entity is originally managed.
Detached entities will be rejected
Entities with an identity but not associated with a persistence context
Author author = new Author(1);
author.setFirstName("dr");
...
logger.debug("creating author: {}", author);
logger.debug("em.contains(author)={}", em.contains(author));
try {
em.persist(author);
fail("did not detect detached entity");
} catch (PersistenceException ex) {
logger.debug("caught expected exception:" + ex.getLocalizedMessage(), ex);
}
logger.debug("em.contains(author)={}", em.contains(author));
-creating author:ejava.examples.daoex.bo.Author@ad339b, id=1, ... -em.contains(author)=false -caught expected exception:javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: ejava.examples.daoex.bo.Author -em.contains(author)=false
<T> T find(Class<T> entityClass, Object primaryKey);
<T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties);
Searches for the entity by primary key value
Returns managed entity if found, else null
Properties permitted for vendor-specific values and ignored if not understood
<T> T getReference(Class<T> entityClass, Object primaryKey);
Searches for the entity by primary key
Returns a LAZY load reference if found
Throws EntityNotFoundException if not exist
//create initial author
Author author = new Author();
...
em.persist(author);
//create detached author with changes
Author author2 = new Author(author.getId());
author2.setFirstName("updated " + author.getFirstName());
...
//merge changes
Author tmp = em.merge(author2);
em.getTransaction().begin();
em.getTransaction().commit();
...
//verify results
assertFalse("author2 is managed", em.contains(author2));
assertTrue("tmp Author is not managed", em.contains(tmp));
assertSame("merged result not existing managed", author, tmp);
...
//verify changes were made to the DB
Author author3 = em.find(Author.class, author.getId());
assertEquals("updated " + firstName, author3.getFirstName());
Update database with state of detached object
State of detached object copied into managed entity or new instance created
Merging a managed entity is ignored. CascadeType.MERGE and ALL relationships are propagated
Merging a removed entity instance results in an IllegalArgumentException
Includes automatic checking of @Version
property
Could be replaced with manual merge
public Author update(Author author) {
Author dbAuthor = em.find(Author.class, author.getId());
dbAuthor.setFirstName(author.getFirstName());
dbAuthor.setLastName(author.getLastName());
dbAuthor.setSubject(author.getSubject());
dbAuthor.setPublishDate(author.getPublishDate());
return dbAuthor;
}
The above manual merge will successfully merge a transient entity -- but what errors and conditions does it not account for?
void remove(Object entity);
Managed entity is removed from database
Actual delete time depends on transaction active and FlushMode
Extended Persistence Context - queues delete until transaction active
New entities are ignored but CascadeType.REMOVE and ALL relationships are cascaded
logger.debug("em.contains(author)={}", em.contains(author));
em.remove(author);
logger.debug("em.contains(author)={}", em.contains(author));
-em.contains(author)=false -HHH000114: Handling transient entity in delete processing -em.contains(author)=false
Detached entities are rejected
Author author = new Author(1);
...
try {
em.remove(author);
fail("did not reject removal of detached object");
} catch (IllegalArgumentException ex) {
logger.debug("caught expected exception:" + ex);
}
-caught expected exception:java.lang.IllegalArgumentException: Removing a detached instance ejava.examples.daoex.bo.Author#1
Removed entities are ignored
Author author = new Author();
...
logger.debug("peristed: {}", author);
logger.debug("em.contains(author)={}", em.contains(author));
em.remove(author);
logger.debug("em.contains(author)={}", em.contains(author));
//entity managers will ignore the removal of a removed entity
em.remove(author);
logger.debug("em.contains(author)={}", em.contains(author));
-peristed:ejava.examples.daoex.bo.Author@6c5356, id=50, ... -em.contains(author)=true -em.contains(author)=false -em.contains(author)=false