2012-04-25 8 views
4

ここではJPAで多対多関係を試しています。私はテーブル "tblcourse"と "tblStudent" CourseEntity.java、JPA、多対多関係、以前の関係をすべて削除して新しい関係を入力する

ため、これはStudentEntity.javaためのコードである、

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表現は以下の通りである、 多くのコースに

@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; 
    ......... 
} 

、私はCourseEntity.java、 SQLクエリthrought学生を挿入しようとすると、StudentEntity.java、バックエンドで焼成 SQLクエリは、

delete 
    from 
     tblcourseStudent 
    where 
     studentid=? 

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

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

され、throughtコースを挿入しよう私の場合はどちらも、レコードが削除され、新しいマッピングが挿入されます。 生徒のためのコースを挿入している場合、最初に生徒のためのプレバイズコースがすべて3番目のテーブルから削除され、新しいコースが入力されます

私の質問は、私は昔の関係、私はプログラム的にこれを達成する必要が

天気を保持したいつまり、 または私は が待っている、注釈を変更している、古いコースを削除して、どのように私は達成することができ、学生のための新しいコースを追加したいです返信

これはStudentServiceBean.javaで作成されたコードと "mapStudentToCourses"メソッドが呼び出されます複数のコースにPA単一学生

@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; 
    } 
} 

これは、1コースが複数の生徒にマッピングされたコード、その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

+0

挿入を行うために実行しているコードを投稿できますか? – kyiu

+0

saveメソッドのコードを追加し、persistence.xmlを追加しました –

答えて

1

私は間違っているかもしれませんが、これは普通だと思いますHibernate firstsは関連するテーブルからすべてのレコードを削除します。

これは、x-to-manyアソシエーション(基本的にCollectionを介してマッピングされるアソシエーション)を扱う場合、HibernateのパーシステンスコンテキストはCollectionの識別子に基づいてダーティチェックを行います。

)のは(mapCourseToStudentsを見てみましょうあなたのCourseServiceBeanクラスのメソッド:あなたは本当にHibernateが最初のDELETE文を実行しないようにしたい場合は、コレクションに項目を削除する代わりに新しいの割り当て/追加する必要があり

... 
    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); 
    ... 

カスケードする操作をマッピングデータに収集して設定します。

0

は、既存のリストに新しいコースを追加します。

Collection<Student> moreStudents = ... 

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

(名前に関しては、クラスや変数名の中の* List、* Entityなどの不必要な不要な部分を削除することを検討してください)例:Student、Course、Participation、course.getStudents() - ) – KarlP

0

私は全体の関係リストを上書きしませんでしたし、代わりに私が元のリストに新しいエンティティを追加します。しかし、Hibernateは以前の私の関係をすべて削除します。この記事によると

https://vladmihalcea.com/the-best-way-to-use-the-manytomany-annotation-with-jpa-and-hibernate/

これは、休止状態の現在の行動のようだ、と私たちは、私たちが最初に正しくごエンティティのhashCode()equals()メソッドを実装し、設定を使用する必要があることしたくない場合はManyToMany関係をモデル化する。