【发布时间】:2010-12-15 17:09:40
【问题描述】:
我在我的 Java 应用程序中使用 Hibernate 作为 ORM。 我有一个 Project Person manytomany-relation 并且 Project 是映射所有者。
现在我有一个问题,我想更新项目。该项目有一个 id、一个名称、...和一组人员。做一次更新,Project_Person联接表中的人都被删除了,控制台上的SQL语句:
Hibernate: update Project set description=?, name=? where id=?
Hibernate: delete from Project_Person where project_id=?
但我不希望执行删除语句。
我的 Java 应用程序中有这个:
this.projService.updateProject(p);
其中 p 是项目,但以 POJO 方式没有人员集。所以我想,为了让它“准备好休眠”,我在一个单独的事务中创建了一个 findProjectById,所以我从数据库中获取项目:
Project proj = this.projService.findProjectById(p.getId());
proj.setName(p.getName());
proj.setDescription(p.getDescription());
所以我得到了 Hibernate-ready Project 对象,更改了值,然后告诉他更新项目。但是 Set 在调试器视图中是 PersistentSet 并且其中没有 Persons (我认为,因为它们是延迟加载的)。 但是更新了
session.update(p);
在一个新事务中,我得到了更新语句和不需要的删除语句。 如何避免删除语句?
我是否必须创建一个特殊的 SQL 语句,以便只更新我要更新的数据库表字段?还是有其他/更好的解决方案?
最好的问候。
更新 这会引发 LazyInitializationException:
public Project findProjectById(int projectId) {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session sess = sessionFactory.getCurrentSession();
Transaction tx = sess.beginTransaction();
try {
Project project = (Project)sess.createQuery("from Project where id = "+projectId).list().get(0);
tx.commit();
System.out.println(project.getPersons().size());
return project;
} catch (IndexOutOfBoundsException ex) {
return null;
}
}
调试器的屏幕截图:
http://img94.imageshack.us/img94/2020/screendebugger.png
HibernateUtil
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
// SessionFactory of Hibernate
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure("/hibernate.cfg.xml").buildSessionFactory();
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed. " + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
tx.commit() 之前的屏幕截图
【问题讨论】:
-
很奇怪。在提交事务之前尝试打印大小。
-
我将调试器的屏幕截图放在 tx.commit() 行之前。更新:将 getPersons().size() 放在 tx.commit() 行之前,我明白了!
-
所以,提交后会话关闭。那么我该怎么做才能用不需要的 SQL 删除语句来解决这个问题呢?