what I say is you can do eveything in a single method method. The fact you need flush means your operation need a state provided by the database (@GeneratedValue?).
Romain Manni-Bucau Twitter: @rmannibucau Blog: http://rmannibucau.wordpress.com/ LinkedIn: http://fr.linkedin.com/in/rmannibucau Github: https://github.com/rmannibucau 2014-05-21 21:40 GMT+02:00 Howard W. Smith, Jr. <[email protected]>: > hmmm, create -> edit is useless? > > I guess you are saying that after i 'create', even though I am adding a > related entity (e.g. tree 'has' branch). > > create(tree) > > Branch branch = new Branch(1) > tree.addBranch(branch) > > so, you are saying that the edit(tree) is not necessary? is that the cause > of the issue that i experience when I remove entityManager.flush() ? > > > > > On Wed, May 21, 2014 at 3:31 PM, Romain Manni-Bucau > <[email protected]>wrote: > > > then the issue is the code you do needs atomicity for each JPA operation > > (why you use flush). but this shouldn't be needed. Typically: create -> > > edit is useless. Just create it once ;) > > > > > > > > Romain Manni-Bucau > > Twitter: @rmannibucau > > Blog: http://rmannibucau.wordpress.com/ > > LinkedIn: http://fr.linkedin.com/in/rmannibucau > > Github: https://github.com/rmannibucau > > > > > > 2014-05-21 21:29 GMT+02:00 Howard W. Smith, Jr. <[email protected] > >: > > > > > okay, based on what you said below, > > > > > > On Wed, May 21, 2014 at 2:42 PM, Romain Manni-Bucau > > > <[email protected]>wrote: > > > > > > > @Stateless // or singletong > > > > public class TxBean { > > > > @PersistenceContext EntityManager em; > > > > > > > > public void doSomeStuffAndCommit() { > > > > // em usage > > > > } > > > > } > > > > > > > > > > > > when exiting the method commit will trigger flush > > > > > > > > > > my @Stateless EJB has doSomeStuffAndCommit(), but > doSomeStuffAndCommit() > > is > > > 'usually' SQL SELECTs, and in my Abstract class for @Stateless @EJB, I > > have > > > the following: > > > > > > protected abstract EntityManager getEntityManager(); > > > > > > public void create(T entity) { > > > // 2011-09-17 flush immediately after persist/create > > > getEntityManager().persist(entity); > > > getEntityManager().flush(); > > > } > > > > > > public void create(T entity, Boolean flush) { > > > getEntityManager().persist(entity); > > > if (flush) getEntityManager().flush(); > > > } > > > > > > public void edit(T entity) { > > > // 2011-09-17 flush immediately after merge > > > getEntityManager().merge(entity); > > > getEntityManager().flush(); > > > } > > > > > > public void edit(T entity, Boolean flush) { > > > getEntityManager().merge(entity); > > > if (flush) getEntityManager().flush(); > > > } > > > > > > public void flush() { > > > getEntityManager().flush(); > > > } > > > > > > public void remove(T entity) { > > > // 2011-09-17 flush immediately after remove/merge the > > > managed/detached entity > > > getEntityManager().remove(getEntityManager().merge(entity)); > > > getEntityManager().flush(); > > > } > > > > > > public void remove(T entity, Boolean flush) { > > > getEntityManager().remove(getEntityManager().merge(entity)); > > > if (flush) getEntityManager().flush(); > > > } > > > > > > > > > majority of my app, calls the create(T entity), edit(T entity), and > > > remove(T entity) methods above where flush() is called after the > > > entityManager operation. > > > > > > below, is a method I have in a @Singleton bean that is called via > > @Schedule > > > to get some data from email account and write data to database. > > > > > > again, the method below is only one of the methods that is in the > > > @Singleton bean. > > > > > > private void createAuditTrail(String relatedEntityName, > > > Object relatedEntityObj, > > > String description) { > > > > > > AuditTrail current = new AuditTrail(); > > > current.setDescriptionTx(description); > > > try { > > > Users user = getUser("system"); > > > if (user == null) { > > > logger.info("Error adding AUDIT TRAIL; 'system' user > > does > > > not exist"); > > > return; > > > } > > > current.setUserName(user); > > > current.setAuditTrailId(1); > > > current.setAuditTrailDt(new Date()); > > > ejbFacadeAuditTrail.create(current); > > > // add auditTrail to order > > > if (relatedEntityName.equals("orders")) { > > > Orders order = (Orders) relatedEntityObj; > > > current.addOrder(order); > > > ejbFacadeAuditTrail.edit(current); > > > } > > > } catch (Exception e) { > > > logger.info("Error adding AUDIT TRAIL" + > > > (e.getMessage() != null ? "; " + > e.getMessage() : > > > "")); > > > } > > > } > > > > > > > > > Majority of my app is CDI @SessionScoped or @ViewScoped beans that call > > > @Stateless @EJB to select/create/update/delete data in database. > > > > > > CDI @SessionScoped and @ViewScoped beans will get data via @Stateless > > @EJB, > > > and CDI @SessionScoped and @ViewScoped beans may do some data > > manipulation, > > > and then @Stateless @EJB is called to do the entityManager create(), > > > edit(), remove() to update database, accordingly. > > > > > > The only time I write a lot of logic in @EJBs is when I am preparing > for > > > SQL SELECT. > > > > > > The @Singleton bean example code that I provided above is one of only > > > (@Singleton) @EJBs that have a lot of code that does a specific job. > > > > > > So, when I removed entityManager.flush() from my Abstract class, > earlier, > > > per Jean-Louis's recommendation, some data was saved to database by > > > @Singleton and most of the data was 'not' saved to database. > > > > > > Definition of @Singleton is below: > > > > > > @Singleton > > > @Lock(LockType.WRITE) > > > @AccessTimeout(value = 2, unit = TimeUnit.MINUTES) > > > public class AddEmailRequest { > > > > > >
