[jboss-user] [EJB/JBoss] - EntityManager remove does not remove?

jvojtek do-not-reply at jboss.com
Thu Apr 24 04:39:23 EDT 2008


In my application I need to persist data of plan modeled in memory to database. First data of previous instance of plan is deleted and then inserted the new one (I do not want to perform update for some reason). But if I perform checking before persisting new data, method findAll returns also data that has been just deleted by the same instance of EntityManager. 

I am not able to successfully call method PlannerFacadeEJB.savePlanVersion :-(

OS: MS Windows XP
JAVA: 1.6
JBoss 4.2.2.GA (the same behaviour on 4.0.5)

Situation:

  | @Entity(name = "DBPlanVersion)
  | @Table(name = "PLAN_VERSION")
  | @NamedQueries({
  | @NamedQuery(name = DBPlanVersion.findAll, query = "SELECT a FROM DBPlanVersion a"),
  | @NamedQuery(name = "DBPlanVersion.findByPlanId, query = "SELECT a FROM DBPlanVersion a WHERE a.planId = :planId") 
  | })
  | public static DBPlanVersion implements Serializable {
  |     public static final String findAll = "DBPlanVersion.findAll";
  |     public static final String findByPlanId = "DBPlanVersion.findByPlanId";    
  | 
  |     private int planVersionId;
  |     private int planId;
  |     private String description;
  | 
  |     public DBPlanVersion() {
  |     }
  | 
  |      
  |     @Id
  |     @Column(name = "PLAN_VERSION_ID", nullable = false, length = 10)
  |     @SequenceGenerator(name = "PLAN_VERSION_SEQ", sequenceName = "PLAN_VERSION_SEQ", allocationSize = 1)
  |     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PLAN_VERSION_SEQ")
  |     public int getPlanVersionId() {
  |         return planVersionId;
  |     }
  | 
  |     public void setPlanVersionId(int planVersionId) {
  |         this.planVersionId = planVersionId;
  |     }
  | 
  |     @Basic
  |     @Column(name = "PLAN_ID", nullable = false, length = 10)
  |     public int getPlanId() {
  |         return planId;
  |     }
  | 
  |     public void setPlanId(int planId) {
  |         this.planId = planId;
  |     }
  | 
  |     @Basic
  |     @Column(name = "DESCRIPTION", nullable = true, length = 50)
  |     public String getDescription() {
  |         return description;
  |     }
  | 
  |     public void setDescription(String description) {
  |         this.description = description;
  |     }
  |     
  |     public boolean equals(Object o) {
  |         if (this == o) return true;
  |         if (o == null || getClass() != o.getClass()) return false;
  | 
  |         DBPlanVersion that = (DBPlanVersion) o;
  | 
  |         if (planVersionId != that.planVersionId) return false;
  | 
  |         return true;
  |     }
  | }
  | 
  | 


  | @Stateless(name = "PlannerFacadeEJB")
  | @Remote(PlannerFacade3.class)
  | @Local(PlannerFacade3.class)
  | public class PlannerFacadeBean implements PlannerFacade3 {
  | 
  |     @PersistenceContext(unitName = "xxx")
  |     EntityManager em;
  |     
  |     public void savePlanVersion(int planId, String description) {
  |         em.setFlushMode(FlushModeType.COMMIT);
  |         planVersionFacade3.deleteByPlanId(planId);
  |         planVersionFacade3.addPlanVersion(planId, description);
  |     }
  | }
  | 



  | @Stateless(name = "PlanVersionFacadeEJB")
  | @Local(PlanVersionFacadeLocal)
  | public class PlanVersionFacadeBean implements PlanVersionFacadeLocal {
  | 
  |     @PersistenceContext(unitName = "xxx");
  |     EntityManager em;
  | 
  |     public void deleteByPlanId(int planId) {
  |         // Lets find DBPlanVersion with specified planId
  |         DBPlanVersion dbPlanVersion = findByPlanId(planId);
  | 
  |         if (dbPlanVersion != null) {
  |             log.info("Delete: planId=" + dbPlanVersion.getPlanId() + ", planVersionId=" + dbPlanVersion.getPlanVersionId());
  | 
  |             // ... delete children records in another entity, code omitted 
  |             
  |             // Delete plan versionId itself
  |             em.remove(planVersion3);
  |         }
  |         log.info("DeleteByPlanId: Instance of EntityManager is " + em);
  |     }
  | 
  |     public DBPlanVersion findByPlanId(int planId) {
  |         Query q = em.createNamedQuery(DBPlanVersion.findByPlanId);
  |         q.setParameter("planId", planId);
  |         try {
  |             return (DBPlanVersion) q.getSingleResult();
  |         } catch (NoResultException e) {
  |             return null;
  |         }
  |     }
  | 
  |     public Collection<DBPlanVersion> findAll() {
  |         return em.createNamedQuery(DBPlanVersion.findAll).getResultList();
  |     }
  | 
  |     public DBPlanVersion addPlanVersion(int planId, String description) {
  |         DBPlanVersion newDBPlanVersion = new DBPlanVersion();
  |         newDBPlanVersion.setPlanId(planId);
  |         newDBPlanVersion.setDescription(description);
  |         // Lets check whether plan version with the same plan id already exists
  |         for (DBPlanVersion pv : findAll()) {
  |             if ((pv.getPlanId() == newDBPlanVersion.getPlanId()) && (!pv.equals(newDBPlanVersion))) {
  |                 throw new RuntimeException("Unable to insert plan version with the same planId = " + pv.getPlanId());
  |             }
  |         }
  |         em.persist(newDBPlanVersion);
  |         return newDBPlanVersion;
  |     }
  | }
  | 

Vital questions:
. how is possible that EntityManager does not know about removed entity in findAll method?
. is there any possibility to use caching?
. what is difference between caching queries and EntityBeans?
. if em.setFlushMode is set to AUTO, findAll does not return just deleted entity and new data can be persisted. But there are many SQL called (can see in JProfiler) - is this the only way of solution?

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4146432#4146432

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4146432



More information about the jboss-user mailing list