我刚刚开始使用JPA和hibernate,我已经能够在一个表上插入查询和更新,但我似乎无法删除一个实体。即使在我使用合并函数附加实体之后,程序仍然坚持将其分离。以下是相关代码:
public User getUserByEmail(String email) throws DAOException{
User user = null;
EntityManager em = null; //declare here for use in finally block
try{
//get em for use
EntityManagerFactory factory = JPAUtil.getEntityManagerFactory();
em = factory.createEntityManager();
//setup return type as user
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> criteriaQuery = cb.createQuery(User.class);
Root<User> userRoot = criteriaQuery.from(User.class);
//populate the where clause
criteriaQuery.where(cb.equal(userRoot.get("email"), cb.parameter(String.class, "email")));
Query query = em.createQuery(criteriaQuery);
query.setParameter("email", email);
//actually run the query on db
user = (User) query.getSingleResult();
}catch(Exception ex){
DAOException dE = new DAOException(2, "getUserByEmail failed", ex);
//TODO log
throw dE;
}
//cleanup
finally{
if(em != null && em.isOpen()){
em.close();
}
}
return user; //if not found, will still be null
}
@Override
/*
* (non-Javadoc)
* @see dao.IUserDAO#deleteUser(java.lang.String)
*/
public void deleteUser(String email) throws DAOException {
EntityManagerFactory entityManagerFactory;
EntityManager em = null;
EntityTransaction trans = null;
try{
//search user on email
User user = getUserByEmail(email);
//check we found user with specified email
if(user != null){
//setup for interaction with database
entityManagerFactory = JPAUtil.getEntityManagerFactory();
em = entityManagerFactory.createEntityManager();
//alterations of db must occur in scope of transaction
trans = em.getTransaction();
trans.begin();
em.merge(user); //TODO update find to take transaction as parameter
em.remove(user);
trans.commit();
//explicitly flush here
em.flush();
}else{
//TODO we didn't find the user
}
}catch(Exception ex){
DAOException dE = new DAOException(6, "delete failed", ex);
//TODO log
trans.rollback();
throw dE;
}finally{
if(em != null && em.isOpen()){
em.close();
}
}
}
以下是eclipse控制台的输出: “删除用户#1的已删除实例”。
有人可以解释为什么在我明确调用merge之后这个bean仍然被释放了吗?另外,我该如何解决这个问题呢?感谢。
答案 0 :(得分:1)
指定的分离实体对象的内容被复制到 具有相同标识的现有管理实体对象(即相同类型 和主键)。如果EntityManager不管理这样的实体 对象还构造了一个新的托管实体对象。超然 然而,对象本身保持不变和分离。
即使在合并后,分离的对象本身仍然分离,合并将返回新创建的合并实体
user = em.merge(user); //TODO update find to take transaction as parameter
em.remove(user);