package org.jboss.seam.framework;
import javax.persistence.EntityManager;
import javax.transaction.SystemException;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.persistence.PersistenceProvider;
import org.jboss.seam.transaction.Transaction;
/**
* Base class for Home objects of JPA entities.
*
* @author Gavin King
*
*/
public class EntityHome<E> extends Home<EntityManager, E>
{
private static final long serialVersionUID = -3140094990727574632L;
/**
* Run on {@link EntityHome} instantiation.
* <br />
* Validates that an {@link EntityManager} is available.
*
* @see Home#create()
*/
@Override
public void create()
{
super.create();
if ( getEntityManager()==null )
{
throw new IllegalStateException("entityManager is null");
}
}
/**
* Returns true if the entity instance is managed
*/
@Transactional
public boolean isManaged()
{
return getInstance()!=null &&
getEntityManager().contains( getInstance() );
}
/**
* Flush any changes made to the managed entity instance to the underlying
* database.
* <br />
* If the update is successful, a log message is printed, a
* {@link javax.faces.application.FacesMessage} is added and a transaction
* success event raised.
*
* @see Home#updatedMessage()
* @see Home#raiseAfterTransactionSuccessEvent()
*
* @return "updated" if the update is successful
*/
@Transactional
public String update()
{
joinTransaction();
getEntityManager().flush();
updatedMessage();
raiseAfterTransactionSuccessEvent();
return "updated";
}
/**
* Persist unmanaged entity instance to the underlying database.
* If the persist is successful, a log message is printed, a
* {@link javax.faces.application.FacesMessage } is added and a transaction
* success event raised.
*
* @see Home#createdMessage()
* @see Home#raiseAfterTransactionSuccessEvent()
*
* @return "persisted" if the persist is successful
*/
@Transactional
public String persist()
{
getEntityManager().persist( getInstance() );
getEntityManager().flush();
assignId( PersistenceProvider.instance().getId( getInstance(), getEntityManager() ) );
createdMessage();
raiseAfterTransactionSuccessEvent();
return "persisted";
}
/**
* Remove managed entity instance from the Persistence Context and the
* underlying database.
* If the remove is successful, a log message is printed, a
* {@link javax.faces.application.FacesMessage} is added and a transaction
* success event raised.
*
* @see Home#deletedMessage()
* @see Home#raiseAfterTransactionSuccessEvent()
*
* @return "removed" if the remove is successful
*/
@Transactional
public String remove()
{
getEntityManager().remove( getInstance() );
getEntityManager().flush();
deletedMessage();
raiseAfterTransactionSuccessEvent();
return "removed";
}
/**
* Implementation of {@link Home#find() find()} for JPA
*
* @see Home#find()
*/
@Transactional
@Override
public E find()
{
if (getEntityManager().isOpen())
{
E result = loadInstance();
if (result==null)
{
result = handleNotFound();
}
return result;
}
else
{
return null;
}
}
/**
* Utility method to load entity instance from the {@link EntityManager}.
* Called by {@link #find()}.
* <br />
* Can be overridden to support eager fetching of associations.
*
* @return The entity identified by {@link Home#getEntityClass() getEntityClass()},
* {@link Home#getId() getId()}
*/
protected E loadInstance()
{
return getEntityManager().find(getEntityClass(), getId());
}
/**
* Implementation of {@link Home#joinTransaction() joinTransaction()} for
* JPA.
*/
@Override
protected void joinTransaction()
{
if ( getEntityManager().isOpen() )
{
try
{
Transaction.instance().enlist( getEntityManager() );
}
catch (SystemException se)
{
throw new RuntimeException("could not join transaction", se);
}
}
}
/**
* The Seam Managed Persistence Context used by this Home component
*/
public EntityManager getEntityManager()
{
return getPersistenceContext();
}
/**
* The Seam Managed Persistence Context used by this Home component.
*/
public void setEntityManager(EntityManager entityManager)
{
setPersistenceContext(entityManager);
}
/**
* The name the Seam component managing the Persistence Context.
* <br />
* Override this or {@link #getEntityManager()} if your persistence context
* is not named <code>entityManager</code>.
*/
@Override
protected String getPersistenceContextName()
{
return "entityManager";
}
/**
* Implementation of {@link Home#getEntityName() getEntityName()} for JPA
*
* @see Home#getEntityName()
*/
@Override
protected String getEntityName()
{
try
{
return PersistenceProvider.instance().getName(getInstance(), getEntityManager());
}
catch (IllegalArgumentException e)
{
// Handle that the passed object may not be an entity
return null;
}
}
}