I want to create some sample code for JPA2 that can be run inside a Java EE container.
Running those sample normally require to have a Java EE server but i want to make things easier and to run them using an embedded container + maven.
Which one is better for this kind of "project" ?
Glassfish embedded , JBoss microcontainer or OPENEJB ?
Others ?
Thank you !
The problem to test EJB outside a container is that injections are not performed. I found this solution. In the stateless session bean you have an annotation #PersistenceContext
in a standalone Java-SE environment you need to inject the entitymanager by yourself, whcih can be done in an unittest. This is a fast alternative to an emmbeded server.
#Stateless
public class TestBean implements TestBusiness {
#PersistenceContext(unitName = "puTest")
EntityManager entityManager = null;
public List method() {
Query query = entityManager.createQuery("select t FROM Table t");
return query.getResultList();
}
}
The unittest instantiates the entitymanager and 'injects' it into the bean.
public class TestBeanJUnit {
static EntityManager em = null;
static EntityTransaction tx = null;
static TestBean tb = null;
static EntityManagerFactory emf = null;
#BeforeClass
public static void init() throws Exception {
emf = Persistence.createEntityManagerFactory("puTest");
}
#Before
public void setup() {
try {
em = emf.createEntityManager();
tx = em.getTransaction();
tx.begin();
tb = new TestBean();
Field field = TestBean.class.getDeclaredField("entityManager");
field.setAccessible(true);
field.set(tb, em);
} catch (Exception ex) {
ex.printStackTrace();
}
}
#After
public void tearDown() throws Exception {
if (em != null) {
tx.commit();
em.close();
}
}
}
Related
I faced a problem in another topic (Empty List (not Table) at ManyToMany-Relation) and wonder if my Usage of EntityManager is correct. So what should be the best way to use EntityManager? A few years ago i read something about the DAO-Pattern (like http://www.oracle.com/technetwork/java/dataaccessobject-138824.html) which i used since that. But now when i want to join the class for WebServices i thought a "Service-Layer" would be better, so i build a class like
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
#Path("role")
public class RoleService {
#GET
#Path("ping")
#Produces(MediaType.TEXT_PLAIN)
public String helloWorld() {
return "REST-Web-Service ready for Role.class!";
}
public static void create(Role object) {
EntityManager em = PersistenceUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(object);
tx.commit();
em.close();
}
public static void update(Role object) {
EntityManager em = PersistenceUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.merge(object);
tx.commit();
em.close();
}
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("id/{id}")
public static Role getRole(#PathParam("id") Integer id) {
return load(id);
}
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("name")
public static String getName(#QueryParam("id") Integer id) {
Role role = findById(id);
if (role != null) {
return "[\n {\n \"id\":"+id+",\n \"type\":\"role\",\n \"name\": \"" + role.getName() + "\",\n \"query\":\"success\"\n }\n]";
}
return "[\n {\n \"id\":"+id+",\n \"type\":\"role\",\n \"query\":\"failed\"\n }\n]";
}
public static Role findById(Integer id) {
EntityManager em = PersistenceUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Role object = em.find(Role.class, id);
tx.commit();
em.close();
return object;
}
public static Role load(Integer id) {
EntityManager em = PersistenceUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Role objectResult = em.find(Role.class, id);
tx.commit();
em.close();
return objectResult;
}
public static Role load(Role object) {
EntityManager em = PersistenceUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Role objectResult = em.find(Role.class, object.getId());
tx.commit();
em.close();
return objectResult;
}
public static void deleteById(Integer id) {
EntityManager em = PersistenceUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.remove(em.find(Role.class, id));
tx.commit();
em.close();
}
// #DELETE
// #Path("{id}")
public static void delete(Role object) {
EntityManager em = PersistenceUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.remove(em.find(Object.class, object.getId()));
tx.commit();
em.close();
}
public static List<Role> findByName(String name) {
EntityManager em = PersistenceUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
List<Role> list = em.createQuery("SELECT r FROM Role r WHERE r.name LIKE :name").setParameter("name", "%" + name + "%").getResultList();
tx.commit();
em.close();
return list;
}
}
The PersistenceUtil is
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class PersistenceUtil {
/*
* Name of persistence unit which MUST correlate to persistence-unit name in persistence.xml
*/
private static final String PERSISTENCE_UNIT_NAME = "RoleModel";
private static final EntityManagerFactory entityManagerFactory;
static {
try {
entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
} catch (Throwable ex) {
System.err.println("EntityManagerFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static EntityManagerFactory getEntityManagerFactory() {
return entityManagerFactory;
}
}
But in the article Entity manager best practices it seems different. Se where should i instantiate EntityManager? Should i use better Annotation? Better a Sigleton-Class? Is it ok when i use it in every method?
What do you think?
I think the most common way is using CDI (context and dependency injection) in first place.
Using CDI your DAO gets the EntityManager injected by the application container (Java app server, e.g. Glassfish). It could look something like this:
#Dependent
public class FooDAO {
#PersistenceContext
private EntityManager em;
public FooEntity find(final Number id) throws NoResultException {
return em.find(FooEntity.class, id);
}
public List<FooEntity> findAll() {
return em.createNamedQuery("FooEntity.findAll", FooEntity.class).getResultList();
}
// ...
}
The CDI container takes note of the #PersistenceContext annotation and the Entity Manager gets instantiated, so you don't need to worry about anything related to it. The transactions are also managed by the application server. You probably already have a persistence.xml, where you set all your DB related settings. For the server-managed persistence it needs to define transaction-type="JTA", by the way. See the tons of examples on the web.
In your service or business logic classes (depending on how many layers you want), you would use your DAO class like this:
#Stateless
public class FooManager {
#Inject
private FooDAO fooDAO;
public List<FooEntity> getFoos() {
return fooDAO.findAll();
}
// ...
}
The annotations #Dependent, #Stateless are two of many CDI offers. Depending on this the CDI manager creates one or many instances of your classes. Popular choices include #ViewScoped, #SessionScoped and #ApplicationScoped. When searching the web, don't get confused by JSF's or Seam's annotations. You do not want to use those! The only thing you want to use of JSF is the #Named annotation, and you apply that one only to the backing beans (java classes which are responsible for view). EJB annotations are okay, too. They're mostly compatible with CDI.
The code and suggestions above are about Java EE. Some frameworks are using their own annotations and patterns. Most notable ones are Spring and the Play framework. For these, please refer to the fine docs.
No matter what Pattern you are using there is one rule that is always valid.
Create the EntityManagerFactory only onces. EntityManager can be created on each transaction as it is a cheap object.
In terms of patterns, yes DAO and Repository patterns and their variations are most common.
I fully agree that the CDI method is best. The inversion of control reduces the coupling but maintains cohesion of the system. You also needn't worry about allocation/deallocating the manager.
You can also have N number of persistence-unit's in your persistence.xml and you can assign the EntityManager directly to that unit. Further you can set the Context Type which I have set here as Transaction.
#PersistenceContext(unitName = PersistenceStartupService.BJOND_STORE, type=PersistenceContextType.TRANSACTION)
private EntityManager entityManager;
I encourage folks to break-up large schemas into separate persistence units which also helps with fire-walling access to certain tables. I usually have my IdentityManager (PicketLink) as a separate persistence unit.
I am wondering if there is a better way to update entities after they have been read from the database.
This seems like too much code to do a simple task. I have tried using em.merge() which did not persists the data to the database.
public class PodcastManager {
private EntityManagerFactory emf;
public PodcastManager(EntityManagerFactory emf) {
this.emf = emf;
}
public void updatePodcast(Podcast podcast) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Podcast ptu = em.find(Podcast.class, podcast.getId());
if ( ptu != null) {
ptu.setTitle(podcast.getTitle());
ptu.setDescription(podcast.getDescription());
ptu.setUrl(podcast.getUrl());
ptu.setLang(podcast.getLang());
ptu.setCopyright(podcast.getCopyright());
ptu.setItunesSubtitle(podcast.getItunesSubtitle());
ptu.setItunesAuthor(podcast.getItunesAuthor());
ptu.setItunesSummary(podcast.getItunesSummary());
ptu.setItunesOwnerName(podcast.getItunesOwnerName());
ptu.setItunesOwnerEmail(podcast.getItunesOwnerEmail());
ptu.setItunesImageHREF(podcast.getItunesImageHREF());
ptu.setExplicit(podcast.isExplicit());
}
em.getTransaction().commit();
em.close();
}
}
I managed to get it merge to work as follows.
public void updatePodcast(Podcast podcast) {
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
em.merge(podcast);
em.flush();
} finally {
em.getTransaction().commit();
em.close();
}
}
If you are exercising CRUD procedures do you have to do this (with transaction type: RESOURCE_LOCAL not JTA)
#PersistenceUnit(unitName="mongo")
EntityManagerFactory emf;
EntityManager em;
#Inject
private SomeObj injectableObj;
public void create()
{
em = emf.createEntityManager(); <---- here
SomeObj obj = new SomeObj();
em.persist(obj);
}
public void read()
{
em = emf.createEntityManager(); <---- here
Query query = em.createQuery("Select s from SomeObj s");
}
public void update()
{
em = emf.createEntityManager(); <---- here
SomeObj s = em.find(SomeObj.class, injectableObj.getId());
s.setSomeObj(injectableObj.getSomeObj());
}
public void delete()
{
em = emf.createEntityManager(); <---- here
SomeObj s = em.find(SomeObj.class, injectableObj.getId());
em.remove(s);
}
Question: Is there anyway to inject the EntityManager?
Maybe try to look here for exemples :
Injections EntityManager
I prefer to use : Injection via #PersistenceContext
You can use injection. I use it like this:
#PersistenceContext(unitName = "some_jndi_name")
private EntityManager em;
I am just starting to work with JPA. Based on several tutorials, I have built a simple dynamic web project that includes a GerericDAO as well as a singleton that encapsulates the EntityManagerFactory.
public class PersistenceManager {
private static final PersistenceManager instance = new PersistenceManager();
protected EntityManagerFactory emf;
public static PersistenceManager getInstance() {
return instance;
}
private PersistenceManager() {
}
public EntityManagerFactory getEntityManagerFactory() {
if (emf == null)
createEntityManagerFactory();
return emf;
}
public void closeEntityManagerFactory() {
if (emf != null) {
emf.close(); emf = null;
}
}
protected void createEntityManagerFactory() {
this.emf = Persistence.createEntityManagerFactory("Fusion");
}
}
public class GenericJPADAO<ID extends Serializable, T> implements GenericDAO<ID, T> {
private Class<T> persistentClass;
private EntityManager entityManager;
#SuppressWarnings("unchecked")
public GenericJPADAO() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
protected EntityManager getEntityManager() {
if (entityManager == null)
throw new IllegalStateException("EntityManager has not been set on DAO before");
return entityManager;
}
public T create(T element) throws IOException, IllegalArgumentException {
if (element == null)
throw new IllegalArgumentException();
try {
getEntityManager().persist(element);
return element;
} catch (Exception e) {
throw new IOException("create failed");
}
}
To pull this together in a Transaction method I need something like this (leaving out some of the detail):
DAOFactory factory = DAOFactory.instance(DAOFactory.JPA);
ConfigurationDAO dao = factory.getAddressDAO();
dao.setEntityManager(entityManager);
EntityTransaction ut = entityManager.getTransaction();
try {
ut.begin();
dao.create(address);
ut.commit();
} catch (Exception e) {
ut.rollback();
}
finally {
close??
}
I am very new to this, however it seems awkward to be setting the EntityManager in the DAO Class from the Transaction method. I have previously worked with Hibernate and my DAO classes have been able to retrieve a current Session from a HibernateUtil type class. I am not sure how to achieve a similar structure with JPA / EntityManager whilst maintaining a Thread safe application? Maybe my structure is poorly designed - anyway any advice / guidance much appreciated. I have not been able to find a clear complete example of this. By the way - I am not using Spring in this application.
JPA specification defines a pattern similar to Hibernate's getCurrentSession() - the current EntityManager is injected into field annotated with #PersistenceContext.
However, specification says that support for this pattern should be provided by external environment rather than by JPA providers, therefore you cannot just use it in standalone environment.
In particular, this pattern is supported by Spring Framework and Java EE application servers.
Alternatively, if you cannot use Spring Framework or Java EE application server you can emulate this pattern by storing the current EntityManager in ThreadLocal.
I can't figure out what HibernateUtil is ...
Is it required with JPA?
I use JPA with GWT , is this implementation sufficient?
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public final class EMF {
private static final EntityManagerFactory emfInstance =
Persistence.createEntityManagerFactory("default");
private EMF() {}
public static EntityManagerFactory get() {
return emfInstance;
}
}
And at the use:
public class AccountDao {
public static final EntityManager entityManager() {
return Emf.get().createEntityManager();
}
public void createAccount(Account account) {
EntityManager em = entityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
em.persist(account);
tx.commit();
}
catch (Throwable t) {
t.printStackTrace();
tx.rollback();
}
finally {
em.close();
}
}
}
See this post (Gilead JPA configuration) please. I can't understand yet, how to use HibernateUtil, or HibernateJpaUtil, or PersistentBeanManager stuff ...
To use Gilead with GWT, first change your GWT-RPC service implementations from
public class MyServiceImpl extends RemoteServiceServlet implements MyService {
....
}
into:
public class MyServiceImpl extends PersistentRemoteService implements MyService {
....
}
Then, in the constructor of these classes, call the method setBeanManager(beanManager). Perform the setup as I described in my other answer. Here's the entire code snippet for reference:
public class MyServiceImpl extends PersistentRemoteService implements MyService {
public MyServiceImpl() {
EntityManagerFactory emf = EMF.get();
HibernateJpaUtil hibernateJpaUtil = new HibernateJpaUtil();
hibernateJpaUtil.setEntityManagerFactory(emf);
PersistentBeanManager persistentBeanManager =
GwtConfigurationHelper.initGwtStatelessBeanManager(hibernateJpaUtil);
setBeanManager(persistentBeanManager);
}
// Service methods follow here
}
This is sufficient for the setup - Gilead then uses the bean manager (and HibernateJpaUtils) automatically under the covers, you don't have to interact directly with it. All you have to do is to make sure, that your entities extend net.sf.gilead.pojo.gwt.LightEntity.
Your implementation is pretty sufficient. I would put the factory in the servlet context, rather than making it static though.
But note an important thing here. The above code will work if you are using it purely on the server-side.
Since you are using GWT, it is possible (although I don't think it is rational) to use hibernate "stuff" on the client-side. For that you'd need gilead, where you will need the forementioned utilities.