0

I have a java code where i am updating the staff entity. I am using the application managed entity manager. i have a condition in the login page where if the user has given correct username/password his last login time will be updated.

But the update is not happening and i am getting an exception that the entity has been detached.Please see the Code below :-

GenericDaoImpl.java

public class GenericDaoImpl<T> implements GenericDao<T> {
    private static final String PERSISTENCE_UNIT_NAME = "expenseCalculator";
    private static EntityManagerFactory factory;
    protected static EntityManager em;
    private EntityTransaction etr;

    protected Class<T> domainClass;
    /** The domain object name. */
    protected String domainObjectName = null;

    public synchronized static EntityManagerFactory getfactory(){
        if (null == factory) {
            factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        }
        return factory;
    }

    @SuppressWarnings("unchecked")
    public GenericDaoImpl() {
        em = getfactory().createEntityManager();
        domainClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Entity entityAnn = (Entity) domainClass.getAnnotation(Entity.class);
        if (entityAnn != null && !entityAnn.name().equals("")) {
            domainObjectName = entityAnn.name();
        } else {
            domainObjectName = domainClass.getSimpleName();
        }
    }

    public T create(T t) {
        etr = em.getTransaction();
        etr.begin();
        em.persist(t);
        etr.commit();
        return t;
    }
} 

StaffServiceImpl.java

    public Staff authenticateStaff(LoginBean loginBean) {
            staff = staffDao.findUnique(loginBean.getUserName());
            if (null != staff) {
                if (staff.getIsBlocked() == 'N' && staff != null && staff.getUserName().equals(loginBean.getUserName())
                        && staff.getPassword().equals(loginBean.getPassword())) {
                    staff.setLastLogin(new Date());
//This is giving an exception..
                    new StaffDaoImpl().create(staff);
                    return staff;
                } else if (staff.getIsBlocked() == 'N' && staff != null
                        && staff.getUserName().equals(loginBean.getUserName())) {
                    updateUnsuccessfulAttemptsAndBlockedStatus(staff);
                }
            }
            return null;
        }

StaffDaoImpl.java :-

@Repository
@Component
public class StaffDaoImpl extends GenericDaoImpl<Staff> implements StaffDao {
    public Staff findUnique(String userName) {
        TypedQuery<Staff> query = em.createNamedQuery(domainObjectName + ".findByUserName", domainClass);
        query.setParameter("username", userName);
        Staff staff = null;
        try {
            staff = query.getSingleResult();
        } catch (NoResultException e) {
            staff = null;
        }
        return staff;
    }

In the Class StaffServiceImpl.java you will see that i have made the Staff entity managed y calling the "staffDao.findUnique(loginBean.getUserName());" but still it gives me exception that the entity Staff is detached. Any help is highly appreciated.

Sunny
  • 858
  • 3
  • 17
  • 39
  • What exception are you getting exactly? – Aleksei Budiak Aug 28 '17 at 10:47
  • org.hibernate.PersistentObjectException: detached entity passed to persist: com.expensecalculator.domain.Staff at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:124) at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58) at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:778) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:751) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:756) – Sunny Aug 28 '17 at 10:50
  • Since it's an update you may consider using `merge` instead of `persist` – Alberto S. Aug 28 '17 at 10:50
  • JPA Web application in general can have problem with detached objects (continuous web session isn't compatible with two independent JPA sessions), many solution exist, depends on framework used. Sorry, impossible to express in comment – Jacek Cz Aug 28 '17 at 10:54
  • > `new StaffDaoImpl().create(staff);` Why don't you use Spring to inject StaffDaoImpl but construct it manually? Try to extract it to a private field and mark @Autowired – Kostiantyn Aug 28 '17 at 10:58
  • And finally replace `persist` with `merge` - as described [here](https://stackoverflow.com/a/13837495/8513835]), that will most probably solve your problem. There is a lot of answers to similar questions here on stackoverflow – Kostiantyn Aug 28 '17 at 11:01

1 Answers1

0

I have got the answer, actually ""staffDao.findUnique(loginBean.getUserName())" does not make the Staff entity managed. So i have to use merge so that the Staff entity is managed and any changes to it is persisted to DB.

Sunny
  • 858
  • 3
  • 17
  • 39