2012-09-19 163 views
-1

親愛的朋友我有兩個實體:員工和與OneToMany關聯相關的部門。即員工可以在多個部門工作。我創建了兩個員工和兩個部門。兩名員工都在同一個部門工作。當我保存這些實體時,我得到這個例外。我在這裏給出了我的程序的完整代碼。預先感謝幫助任何人。 代碼: -休眠映射OneToMany通過註釋

- 部門實體---

package anno; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name="annoDept") 
public class AnnoDept { 


    @Id 
    @Column(name = "deptid") 
    private Integer anid; 
    @Column(name = "deptname") 
    private String anname; 

    public Integer getAnid() { 
     return anid; 
    } 

    public void setAnid(Integer anid) { 
     this.anid = anid; 
    } 

    public String getAnname() { 
     return anname; 
    } 

    public void setAnname(String anname) { 
     this.anname = anname; 
    } 

    public boolean equals(Object obj) 
    { 
     if(!(obj instanceof AnnoDept)) 
      return false; 
      if(((AnnoDept)obj).getAnid()==this.getAnid() && ((AnnoDept)obj).getAnname().equalsIgnoreCase(this.getAnname())) 
       return true; 
      return false; 

    } 
} 



--Employee Entity code: -- 

package anno; 

import java.util.HashSet; 
import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 

@Entity 
@Table(name="annoEmp") 
public class AnnoEmp { 
    @Id 
    private Integer empid; 

    @Column(name="EName") 
    private String empname; 
    public Integer getEmpid() { 
     return empid; 
    } 
    public void setEmpid(Integer empid) { 
     this.empid = empid; 
    } 
    public String getEmpname() { 
     return empname; 
    } 
    public void setEmpname(String empname) { 
     this.empname = empname; 
    } 
    public Set<AnnoDept> getDepts() { 
     return depts; 
    } 
    public void setDepts(Set<AnnoDept> depts) { 
     this.depts = depts; 
    } 

    @OneToMany(cascade={CascadeType.ALL}) 
    private Set<AnnoDept> depts=new HashSet<AnnoDept>(); 
} 

-- hibernate.cfg.xml file code: -- 

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC 
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
      "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 
<session-factory> 
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 
    <property name="connection.url">jdbc:mysql://localhost:3306/test</property> 
    <property name="connection.username">root</property> 
    <property name="connection.password">root</property> 
    <property name="hibernate.hbm2ddl.auto">update</property> 
    <property name="hibernate.show_sql">true</property> 
    <property name="hibernate.format_query">true</property> 
    <mapping class="anno.AnnoEmp"/> 
    <mapping class="anno.AnnoDept"/> 

</session-factory> 
</hibernate-configuration> 





--Test code:-- 

package anno; 

import java.util.HashSet; 
import java.util.Set; 

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.hibernate.cfg.AnnotationConfiguration; 

public class AnnoTest { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 

    SessionFactory sf=new AnnotationConfiguration().configure("mypack/hibernate.cfg.xml").buildSessionFactory(); 
    Session hs=sf.openSession(); 
    Transaction tx=hs.beginTransaction(); 

    AnnoDept dept=new AnnoDept(); 
    dept.setAnid(100);dept.setAnname("HR"); 
    AnnoDept dept3=new AnnoDept(); 
    dept3.setAnid(300);dept3.setAnname("Admin"); 
    Set<AnnoDept> deptset1=new HashSet<AnnoDept>(); 

    AnnoEmp e1=new AnnoEmp(); 
    e1.setEmpid(10);e1.setEmpname("Pinku"); 
    deptset1.add(dept);deptset1.add(dept3); 
    e1.setDepts(deptset1);hs.save(e1); 
    AnnoEmp e2=new AnnoEmp(); 
    e2.setEmpid(20);e2.setEmpname("Vijay"); 

    e2.setDepts(deptset1); 
    hs.save(e2); 

    tx.commit(); 
    hs.close(); 
    sf.close(); 
    } 

} 

-- Exception --- 

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: select annodept_.deptid, annodept_.deptname as deptname1_ from annoDept annodept_ where annodept_.deptid=? 
Hibernate: select annodept_.deptid, annodept_.deptname as deptname1_ from annoDept annodept_ where annodept_.deptid=? 
Hibernate: insert into annoEmp (EName, empid) values (?, ?) 
Hibernate: insert into annoDept (deptname, deptid) values (?, ?) 
Hibernate: insert into annoDept (deptname, deptid) values (?, ?) 
Hibernate: insert into annoEmp (EName, empid) values (?, ?) 
Hibernate: insert into annoEmp_annoDept (annoEmp_empid, depts_deptid) values (?, ?) 
Hibernate: insert into annoEmp_annoDept (annoEmp_empid, depts_deptid) values (?, ?) 
Hibernate: insert into annoEmp_annoDept (annoEmp_empid, depts_deptid) values (?, ?) 
Hibernate: insert into annoEmp_annoDept (annoEmp_empid, depts_deptid) values (?, ?) 
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) 
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:145) 
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298) 
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) 
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000) 
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338) 
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106) 
    at anno.AnnoTest.main(AnnoTest.java:39) 
Caused by: java.sql.BatchUpdateException: Duplicate entry '100' for key 2 
    at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:665) 
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) 
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246) 
    ... 8 more 



Thanks 
Dal Singar yadav 

回答

0

你不應該重用你的「deptset1」他們是相同的一組實例,但每個關係是由單獨的AnnoEmp實例擁有。因此,每個AnnoEmp必須有兩個不同的Set實例。但是你已經在實體類初始化器中有了這個。那麼爲什麼不直接重用每個實例。見下:

AnnoDept dept=new AnnoDept(); 
dept.setAnid(100);dept.setAnname("HR"); 
hs.save(dept);     // ADDED LINE (TO HELP DEBUG) 
hs.flush();      // ADDED LINE (TO HELP DEBUG) 

AnnoDept dept3=new AnnoDept(); 
dept3.setAnid(300);dept3.setAnname("Admin"); 
hs.save(dept3);     // ADDED LINE (TO HELP DEBUG) 
hs.flush();      // ADDED LINE (TO HELP DEBUG) 
Set<AnnoDept> deptset1;     // REMOVED =new HashSet<AnnoDept>(); 

AnnoEmp e1=new AnnoEmp(); 
e1.setEmpid(10);e1.setEmpname("Pinku"); 
hs.save(e1);     // ADDED LINE (TO HELP DEBUG) 
hs.flush();      // ADDED LINE (TO HELP DEBUG) 
despset1 = e1.getDepts();    // ADDED LINE 
deptset1.add(dept);deptset1.add(dept3); 
//e1.setDepts(deptset1);     // NOT NEEDED 
//hs.save(e1); 
hs.update(e1);     // CHANGED TO UPDATE (TO HELP DEBUG) 
hs.flush();      // ADDED LINE (TO HELP DEBUG) 

AnnoEmp e2=new AnnoEmp(); 
e2.setEmpid(20);e2.setEmpname("Vijay"); 
hs.save(e2);     // ADDED LINE (TO HELP DEBUG) 
hs.flush();      // ADDED LINE (TO HELP DEBUG) 
despset1 = e2.getDepts();    // ADDED LINE 
deptset1.add(dept);deptset1.add(dept3); // ADDED LINE 
//e2.setDepts(deptset1);     // NOT NEEDED 
//hs.save(e2); 
// WE ARE EXPECTING YOUR ERROR TO OCCUR HERE WHEN STORING THE NEW 
// DATA IN THE 'Set' TO DATABASE 
hs.update(e2);     // CHANGED TO UPDATE (TO HELP DEBUG) 
hs.flush();      // ADDED LINE (TO HELP DEBUG) 
+0

親愛的Darryl Miles感謝您查看我的問題。但是你的回答是不正確的,我再次用你改變的代碼得到同樣的異常。 – Vijay

+0

誰創建了數據庫模式?正在使用自動模式生成?您得到的實際錯誤與UNIQUE KEY約束有關(如果您重新使用「Set」對象實例,則會發生這種情況)。 'Set'由表annoEmp_annoDept表示。嘗試在每個代碼語句之間添加'hs.flush();'。嘗試找到導致問題的確切線路。 –

+0

我很抱歉地說Darryl仍然給代碼不起作用。請在您的系統上運行,然後與我分享。 – Vijay