2012-04-25 74 views
4

在這裏我試圖在JPA多對多的關係,我創建表「tblcourse」和「tblStudent」,一個學生可以爲CourseEntity.java,JPA,多對多的關係,刪除所有以前的關係,並進入新的關係

註冊到許多課程,

create table tblcourse(
    id integer primary key, 
    name varchar(100), 
    duration integer 
); 

create table tblcourseStudent(
    studentid integer references tblstudent(studentId), 
    courseId integer references tblcourse(id), 
    constraint pk_composit_cs primary key(studentid,courseId) 
) 

Create table tblStudent(
    studentId integer primary key, 
    …….. 
    …. 
); 

上述關係的JPA表示如下, 這是StudentEntity.java代碼,

@Entity 
@Table(name="TBLSTUDENT") 
public class StudentEntity implements Serializable{ 

private static final long serialVersionUID = 100034222342L; 

@Id 
@Column(name="STUDENTID") 
private Integer studentId; 

@Column(name="STUDENTNAME") 
private String studentName; 

@Column(name="CONTACTNO") 
private String contactNumber; 

@Embedded 
private StudentAddress address; 

@ManyToOne(fetch=FetchType.LAZY) 
@JoinColumn(name="DEPTID") 
private DeptEntity deptEntity; 

@ManyToMany(fetch=FetchType.LAZY) 
@JoinTable(name="tblcourseStudent", 
      [email protected](name="studentid"), 
      [email protected](name="courseId")) 
    private List<CourseEntity> courseList; 
.... 
..... 
..... 
} 

這個代碼

@Entity 
@Table(name="TBLCOURSE") 
public class CourseEntity implements Serializable{ 

     public CourseEntity(){ 

     } 

    public CourseEntity(Integer courseId,String courseName,Integer courseDuration){ 
     this.courseId = courseId; 
     this.courseName = courseName; 
     this.courseDuration = courseDuration; 
    } 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -2192479237310864341L; 

    @Id 
    @Column(name="ID") 
    private Integer courseId; 

    @Column(name="NAME") 
    private String courseName; 

    @Column(name="DURATION") 
    private Integer courseDuration; 

    @ManyToMany(fetch=FetchType.LAZY) 
    @JoinTable(name="tblcourseStudent", 
       [email protected](name="courseId"), 
       [email protected](name="studentid")) 
    private List<StudentEntity> studentList; 
    ......... 
} 

現在,當我嘗試插入課程throught StudentEntity.java, 在後臺觸發的SQL查詢

delete 
    from 
     tblcourseStudent 
    where 
     studentid=? 

insert 
    into 
     tblcourseStudent 
     (studentid, courseId) 
    values 
     (?, ?) 

insert 
    into 
     tblcourseStudent 
     (studentid, courseId) 
    values 
     (?, ?) 

,當我嘗試插入學生throught CourseEntity.java, 的SQL查詢發射如下,

delete 
    from 
     tblcourseStudent 
    where 
     courseId=? 

insert 
    into 
     tblcourseStudent 
     (courseId, studentid) 
    values 
     (?, ?) 

在我的情況下,記錄被刪除,並插入新的映射。 因此,如果我爲學生插入課程,首先將從第三個表中刪除所有學生的previouse課程,並且將輸入新課程,

所以,我的問題是,如果我不要刪除舊的課程,並添加新的課程,爲學生如何能夠做到,也就是我要保留舊關係,

天氣我必須以編程方式實現這一目標, 或我修改了註解, 等待回覆

這個代碼寫在StudentServiceBean.java和方法「mapStudentToCourses」被調用時,我們可以每年一個學生到多個課程

@Stateless 
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class StudentServiceBean implements StudentService{ 


@PersistenceContext(unitName="forPractise") 
private EntityManager entityMgr; 

@Resource 
private SessionContext sessionContext; 

@EJB 
private DeptService deptService; 
.......... 
...... 
... 

@Override 
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public void mapStudentToCourses(Integer studentId,String courseIdList) throws Exception{ 
    List<CourseEntity> courseList = null; 
    StudentEntity studentEntity = null; 
    TypedQuery<CourseEntity> courseQuery = null;   
    String query = "select c from CourseEntity c where c.courseId in ("+courseIdList+")"; 
    try{ 
     courseQuery = entityMgr.createQuery(query,CourseEntity.class); 
     courseList = courseQuery.getResultList(); 
     studentEntity = entityMgr.find(StudentEntity.class, studentId); 
     studentEntity.setCourseList(courseList); 
     entityMgr.merge(studentEntity);   
    }catch(Exception e){ 
     sessionContext.setRollbackOnly(); 
     throw e; 
    } 
} 

這是代碼,當一門課程被映射到多個學生,其CourseServiceBean.java

@Stateless 
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class CourseServiceBean implements CourseService{ 

@PersistenceContext(name="forPractise") 
private EntityManager em; 

@Resource 
private SessionContext sessionCtx; 

private Map<Integer, String> durationCode = null; 

@EJB 
private StudentService studentService; 
........ 
...... 
... 

@Override 
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public void mapCourseToStudents(Integer courseId,String studentIdList) throws Exception{ 
    List<StudentEntity> studentEntityList = null; 
    TypedQuery<StudentEntity> studentQuery = null; 
    String query = "select s from StudentEntity s where s.studentId IN ("+studentIdList+")"; 
    CourseEntity courseEntity = null; 
    try{ 
     studentQuery = em.createQuery(query, StudentEntity.class); 
     studentEntityList = studentQuery.getResultList(); 
     courseEntity = em.find(CourseEntity.class,courseId); 
     courseEntity.setStudentList(studentEntityList); 
     em.merge(courseEntity); 
    }catch(Exception e){ 
     sessionCtx.setRollbackOnly(); 
     throw e; 
    } 
} 
}  

這是我的persistence.xml文件,

<?xml version="1.0" encoding="UTF-8"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
      version="2.0"> 
    <persistence-unit name="forPractise" transaction-type="JTA"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <jta-data-source>jdbc/app</jta-data-source> 
     <class>com.entity.StudentEntity</class> 
     <class>com.entity.DeptEntity</class> 
     <class>com.entity.CourseEntity</class>  
     <properties> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" /> 
      <property name="hibernate.show_sql" value="true" /> 
      <property name="hibernate.format_sql" value="true" />       
     </properties> 
    </persistence-unit> 
</persistence> 

等待回覆....

+0

你可以發佈配置文件persistence.xml嗎? – perissf 2012-04-26 06:20:47

+0

您可以發佈您正在運行的代碼以進行插入嗎? – kyiu 2012-04-26 06:46:59

+0

添加了save方法的代碼,並且還添加了persistence.xml – 2012-04-26 09:34:03

回答

1

我可能是錯的,但我認爲這是正常的,當您正在進行插入操作,Hibernate將首先刪除關聯表中的所有記錄。

這就是原因:在使用x對多關聯(基本上是通過集合映射的關聯)時,Hibernate的持久性上下文將根據集合的標識符執行髒檢查。

讓我們以mapCourseToStudents()方法從CourseServiceBean類:

... 
    studentQuery = em.createQuery(query, StudentEntity.class); 
    studentEntityList = studentQuery.getResultList(); 
    courseEntity = em.find(CourseEntity.class,courseId); 
    courseEntity.setStudentList(studentEntityList); // replacing the previous Collection by the one you retrieved by querying the DB !!! 
    em.merge(courseEntity); 
    ... 

如果你真的想避免休眠先執行DELETE語句,你應該添加/刪除項目的集合,而不是分配新在映射數據中收集和配置要級聯的操作。

0

添加新的課程,以現有的列表:

Collection<Student> moreStudents = ... 

course = em.find(CourseEntity.class,courseId); 
course.getStudentList().addAll(moreStudents); 
+0

(關於命名,考慮去除不必要的混亂,比如* List,* Entity等等在你的類和變量名稱中,例如:Student,Course,Participation,course.getStudents()Less to write and read: - ) – KarlP 2012-04-26 22:09:32