为了更多地了解 Hibernate,我编写了一些代码来创建一些实体并将它们保存在数据库中,然后尝试删除其中一个实体。
实体客户的映射文件将 id 生成器设置为 native 。我正在使用 postgresql 作为数据库。
...
<class name="Customer" table="CUSTOMER">
<id column="CUSTOMER_ID" name="customer_id" type="java.lang.Long">
<generator class="native"/>
</id>
...
我遇到了 hibernate.NonUniqueObjectException。
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.me.hibernatestore.Customer#129]
完整堆栈跟踪 here
我启动了 eclipse 调试器,发现所涉及的对象在所有涉及的方法中具有相同的地址..
代码的相关部分是
public class Main {
CustomerDao custdao;
Customer mark;
public void storeDemo(){
custdao = DaoFactory.getCustomerDao();
createCustomers();
updateEntities();
deleteCustomer(mark);
}
private void createCustomers() {
mark = new Customer();
mark.setName("mark");
mark.setEmailAddress("mark@home");
mark.setAddress("121,3rd avenue");
mark.setCity("San Diego");
mark.setState("CA");
mark.setCountry("U.S.A");
}
private void updateEntities() {
Transaction tx = null;
Session session = HibernateUtil.getCurrentSession();
try{
tx = session.beginTransaction();
custdao.saveOrUpdateCustomer(mark);
tx.commit();
}catch(RuntimeException e){
tx.rollback();
throw e;
}
}
private void deleteCustomer(Customer cust){
Transaction tx = null;
Session session = HibernateUtil.getCurrentSession();
try{
tx = session.beginTransaction();
String custName = cust.getName();
custdao.deleteCustomer(cust);
tx.commit();
}catch(RuntimeException e){
tx.rollback();
throw e;
}
}
public static void main(String[] args) {
new Main().storeDemo();
}
}
在调试器的帮助下,我找到了对象“mark”的地址
Main.createCustomers(): mark-> Customer@2bc3f5
CustomerDaoImpl.saveOrUpdateCustomer(Customer customer):customer-> Customer@2bc3f5
BaseDaoImpl.saveOrUpdate(T obj):obj-> Customer@2bc3f5
Main.deleteCustomer(Customer customer):customer-> Customer@2bc3f5
CustomerDaoImpl.deleteCustomer(Customer customer):customer-> Customer@2bc3f5
BaseDaoImpl.delete(T obj):obj-> Customer@2bc3f5
进一步试验,我修改了代码,通过 dao.findById() 得到了一个具有相同 ID 的不同对象,并在 deleteCustomer() 中使用了它。这次代码没有抛出任何异常
public class Main {
CustomerDao custdao;
Customer mark;
public void storeDemo(){
custdao = DaoFactory.getCustomerDao();
createCustomers();
updateEntities();
Long mark_id = mark.getCustomer_id();
Customer mark2 = getCustomer(mark_id);
deleteCustomer(mark2);
}
private Customer getCustomer(Long id){
Transaction tx = null;
Customer cust = null;
Session session = HibernateUtil.getCurrentSession();
try{
tx = session.beginTransaction();
return custdao.findCustomerById(id);
}catch(RuntimeException e){
throw e;
}
}
...
}
有人可以解释这种行为吗?我对错误消息中“具有相同标识符值的不同对象”部分的理解是模糊的。在第一种情况下,调试器中显示的对象具有代码中到处都是相同的内存地址,那怎么可能是不同的对象呢?
真诚的
吉姆
最佳答案
这个异常通常发生在处理detached objects的时候.为了避免这种情况,您必须获取该对象并在同一 session 中将其删除或 reattach它到 session ,然后删除它。 希望这对您有所帮助!
关于java - 理解 hibernate 中的 NonUniqueObjectException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6857962/