I'm just trying to get to know JSF and JPA but whenever I try to persist an object into the database it seems to not write away.
Here's the code I'm using:
#Named
#ManagedBean
#SessionScoped
public class BestemmingController implements Serializable{
#PersistenceUnit(unitName="RealDolmenTravelShopPU")
#PersistenceContext(unitName="RealDolmenTravelShopPU")
EntityManagerFactory emf = null;
public void submit(){
try{
emf = Persistence.createEntityManagerFactory("RealDolmenTravelShopPU");
EntityManager em = emf.createEntityManager();
//EntityTransaction et = em.getTransaction();
//et.begin();
Bestemming nieuweBestemming = new Bestemming();
Land gezochtLand = em.find(Land.class, selectedLand);
nieuweBestemming.setLand(gezochtLand);
nieuweBestemming.setNaam(bestemmingNaam);
em.persist(nieuweBestemming);
//et.commit();
//em.flush();
em.close();
}catch (Exception e){
e.printStackTrace();
}finally{
emf.close();
}
}
I tried using the EntityTransaction but it just stopped my application, without any errors or anything. So I left it out, but still it didn't write away.
So then I tried calling flush seperately, but that didn't do anything either.
I'm really stumped as to why this isn't working. It's probably some newbie mistake, but I would love it if someone here could help me out.
Thanks in advance!
First, are you able to write to the logs? Starting a transaction when specifying the persistence unit uses JTA will throw an exception, so it is likely you have just been missing exceptions in your container log files.
Second, this is a JTA PU, so it needs a JTA transaction started that the EM gets associated to, and you will want to inject the em rather than create a factory yourself. Check out the JPA application server examples here first to see how they are set up:
http://wiki.eclipse.org/EclipseLink/Examples/JPA
Hey I found out why it was that the transaction wasn't running: the implementation I used didn't use JTA, it used a RESOURCE_LOCAL persistence unit. That was something I just looked over when I set up my project.
Good thing my buddy told me to check the server logs.
Related
I have the following code:
public Category findCategoryById(Long id) {
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
Category category = categoryDAO.findCategoryById(em, id);
em.getTransaction().commit();
return category;
} catch (Exception e) {
throw e;
} finally {
em.close();
}
}
I'm handling the exceptions in my controller, but I want to make sure that entity manager is closed. I don't like that I am catching and re-throwing the error. I'm hoping to find better suggestions.
thanks
The best way is to not have to care about it. If your Entity Manager is container managed (for example if you are using ejb or spring and you haven't forced a specific bean/application managed behaviour) you should let the container handle the opening/close of the transaction and in general to worry about your persistence context. It's easier, safer and, with the exclusion of very specific cases, better. The manual close of the Entity Manager should be directly handled by you only in case of application managed context, to avoid connection pool exhaustion or other problems.
I'm using EJB3 and JPA2 in a project containing several modules.
Lately i have noticed that the DB-records won't rollback on exception. After doing some research i found that entity manager commits the transaction on flush immediatly even before the method ends, so that it can't rollback on exception.
I inject entity manager using
#PersistenceContext
private EntityManager entityManager;
To create a new record is persist and flush beeing called in the same class
entityManager.persist(entity);
entityManager.flush();
Even if i call throw new RuntimException("") right after flush, it wont rollback. On debug after flush is invoked i can select the DB-record with a database tool, before the method ends.
I already checked the persistence.xml and found nothing unusual. I dont use any other specifig configuration.
I'm out of ideas what might cause this behavior. I appriciate any clue.
You need to specify transaction boundaries, otherwise a new transaction will be opened and commited after each data manipulation query (INSERT, UPDATE, DELETE). As em.flush() will trigger such SQL query to be executed, it will open an implicit transaction and commit it if the SQL is successful, rollback in case of error.
In order to set transaction boundaries and make a RuntimeException trigger a rollback, the best option is to call entityManager methods from an EJB object. You must use a JTA datasource, not RESOURCE_LOCAL. If you don't use JTA datasource, you need to manage transactions by yourself, ie. by using entityManager.getTransaction() object.
Outside of an EJB, or with non-JTA datasource, you do not have any transaction open, unless you start it yourself by calling entityManager.getTransaction().begin(). However, in this way, your transaction will not be rolled back when Exception is thrown. Instead, you must roll back in catch block. This is mostly outside of Java EE container, in a Java SE application. In Java EE, I strongly suggest to use JTA datasource. Example:
public class NotAnEJB {
public persistEntity(EntityManager em, MyEntity entity) {
em.getTransaction().begin();
try {
em.persist(entity);
em.flush();
if (shouldFail()) {
throw new RuntimeException();
}
em.commit();
} catch (Exception e) {
em.rollback();
}
}
}
I am trying to create a testcase for my DAO classes that use plain Hibernate API (no Spring stuff like HibernateTemplate,HibernateDaoSupport), just like this:
sessionFactory.getCurrentSession().save(obj);
I have the appropriate sessionFactory and transactionManager definition in spring context as shown in the spring docs.
What I want is to open a transaction in my start up code and rollback at the end.
So this is different from the default Spring unit testing supporting concept of transaction for every test method call and so I could not extend AbstractTransactionalTestNGSpringContextTests.
I need a way to start a transaction and somehow feed it in session factory. I feel this should be extremely easy but could not achieve after lot of reading and experiments.
Any help would be greatly appreciated.
If you don't want to use HibernateTemplate, you can use transactionManager directly as described in 10.6.2 Using the PlatformTransactionManager.
try {
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
...
tx.commit();
session.close();
} catch (SomeException e) {
tx.rollback();
...
}
#Transactional(readOnly = false, propagation = Propagation.REQUIRED)
annotate the test method using above
In my code I am updating two table, one after the other.
update(table1_details);
update(table2_details);
So if the update fails in table1 , table2 should not be updated or should be rolled back.
How to handle this situation. I know I have to use transaction. Can some one help with code !!!
I am using Java with spring and hibernate .
The question is a bit broad and there are several ways to implement this but I would:
Use Spring to inject Hibernate SessionFactory into DAOs objects.
Use Spring to inject DAOs in a service object and call them inside a business method.
Use Spring declarative transaction management at the business method level (either with Spring AOP or #Transactional).
Something like this:
#Transactional
public void doSomething() {
dao1.foo();
dao2.bar();
}
For more details on the configuration, check the Chapter 9. Transaction management of the Spring documentation.
I can't recall the correct api, but something like this:
Transaction tx = em.getTransaction();
tx.begin();
try {
update1(); update2();
}
catch(Exception e) {
failed = true
}
finally {
if( !failed ) tx.commit();
else tx.rollbacl();
}
I have a slow memory leak in my Java application. I was wondering if this could be caused by not always closing the Entitymanager when used. However using myeclipse to generate DB code, I'm getting methods like this:
public Meit update(Meit entity) {
logger.info("updating Meit instance");
try {
Meit result = getEntityManager().merge(entity);
logger.info("update successful");
return result;
} catch (RuntimeException re) {
logger.error("update failed");
throw re;
}
}
Which never close the EntityManager. Considering this is generated code, I'm wondering who's right, me or the IDE.
As #Ruggs said if you are managing the EntityManager lifecycle yourself (as opposed to having CMP Container Managed Persistence done by a J2EE) then you need to close the EntityManager yourself or at least call EntityManager.clear() to detach entities.
EntityManager are lightweight object so there is no need for just having one, you can create one for each transaction and close it after the transaction is committed.
All the entities that load/persist through an EntityManager stay in memory until you explicitly detach the entities from it (via EntityManager.detach() or EntityManager.clear() or EntityManager.close()). So it's better to have short-lived EntityManagers. If you persist 1000000 entities via the same EntityManager without detaching them after you will get a OOME (doesn't matter if you persist each entity in it's own EntityTransaction).
It's all explained in this post http://javanotepad.blogspot.com/2007/06/how-to-close-jpa-entitymanger-in-web.html.
As an example (taken from the earlier post) if you want to avoid "memory leaks" you should do something like this (if you are not using CMP):
EntityManager em = emf.createEntityManager();
try {
EntityTransaction t = em.getTransaction();
try {
t.begin();
// business logic to update the customer
em.merge(cust);
t.commit();
} finally {
if (t.isActive()) t.rollback();
}
} finally {
em.close();
}
Entity managers should generally have the same lifecycle as the application and not be created or destroyed on a per-request basis.
Your "memory leak" may be nothing more than the caching JPA is doing. You don't say which JPA provider you use but I know from experience that EclipseLink by default does extensive caching (which is part of the alleged benefits of JPA and ORM in general).
How do you know you have a memory leak?
Check whether it's really a leak
if so get the Eclipse Memory Analyzer and analyze it.
The blog posts here might also be useful.
It sounds like you are using an application managed EntityManager. You will need to call close the EntityManager yourself, it's part of the spec. You will also need to close the EntityManagerFactory when you shutdown your webapp.
I'd recommend using something like OpenEJB or Springframework to manage the EntityManager/EntityMangerFactory for you.