2011-12-06 59 views
0

我有這樣的簡單情況:冬眠NonUniqueObjectException保存時更新

@Entity 
public class Customer{ 

    @ManyToMany(fetch=FetchType.EAGER) 
    @Cascade(CascadeType.SAVE_UPDATE) 
    private List<Product> products=new ArrayList<Product>(); 

} 

@Entity 
public class Produtc{ 

    @ManyToOne 
    @Cascade(CascadeType.SAVE_UPDATE) 
    private Category category; 
} 

@Entity 
public class Category{ 

    private String name; 
} 

程序中插入新的客戶:

Customer customer=new Customer(); 
//customer.set data 
Product p=dao.getProductBySomeUserInput... 
if(p==null){ 
    p=new Product(); 
    //p.set data 
} 
customer.addProduct(p); 
dao.save(customer); //this row throw NonUniqueObjectException on Category class 

我怎樣才能解決這個問題?我認爲問題與CascadeType.SAVE_UPDATE有關,但我需要它... 謝謝大家。


UPDATE

我發現這個問題,這就是如何將它複製:

​​

所以,如果P和P 1具有不同的類別有沒有probs,但如果p和p1具有相同的類別,我在類別上有NonUniqueObjectException becouse相同的類別在會話中,並且hibernate嘗試save_update它的。

我需要產品和類別實體中的CascadeType.SAVE_UPDATE,所以如何解決此問題? 謝謝。

+0

可能的重複http://stackoverflow.com/questions/3543716/hibernate-and-nonuniqueobjectexception –

+0

仍然無法解決。 – blow

+0

是否有機會在客戶對象上設置ID?在hibernate的會話中是否存在具有相同ID的對象? – aishwarya

回答

2

這個問題可能是由於不良的事務管理。你所有的代碼都應該在一個事務中完成,而不是每個DAO調用都有一個事務。服務層應該是劃分事務的層,而不是DAO層。

我能想象休眠做什麼:

  1. 你叫dao.get(Product.class, 2)。這將返回指向ID 67(例如)類別的分離產品。結果是分離的,因爲事務在對DAO的調用結束時結束。
  2. 您致電dao.get(Product.class, 3)。這將返回指向ID 67(例如)類別的分離產品。但由於調用在另一個事務中運行,因此您會得到另一個不同的Category實例(與第一個實例具有相同的ID)。
  3. 您可以在產品上調用saveOrUpdate。這級聯到類別,因此Hibernate必須將類別1和類別2附加到會話。由於它們都具有相同的ID,所以級聯中的一個可能無法完成。

如果您使用單個事務來獲取這兩種產品,它們將具有相同的類別實例,並且不會發生問題。調用merge而不是saveOrUpdate也應該起作用:Hibernate會將這兩個類別的狀態複製到第三個附加的類別中。但是,正確的做法是使用涉及這兩個DAO調用的事務。