Hibernate通过Annotation映射OneToMany

时间:2012-09-19 15:12:52

标签: hibernate one-to-many

亲爱的朋友我有两个实体:与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

1 个答案:

答案 0 :(得分:0)

您不应该重用“deptset1”它们是SAME Set实例,但每个关系都由单独的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)