java – JPA,多对多关系,删除所有先前的关系并输入新的关系
在这里,我正在尝试JPA中的多对多关系,我创建了表“tblcourse”和“tblStudent”,学生可以注册许多课程,
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",joinColumns=@JoinColumn(name="studentid"),inverseJoinColumns=@JoinColumn(name="courseId")) private List<CourseEntity> courseList; .... ..... ..... } 这是CourseEntity.java的代码, @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",joinColumns=@JoinColumn(name="courseId"),inverseJoinColumns=@JoinColumn(name="studentid")) private List<StudentEntity> studentList; ......... } 现在,当我尝试通过StudentEntity.java插入课程时, delete from tblcourseStudent where studentid=? insert into tblcourseStudent (studentid,courseId) values (?,?) insert into tblcourseStudent (studentid,?) 而且,当我尝试通过CourseEntity.java插入学生时, delete from tblcourseStudent where courseId=? insert into tblcourseStudent (courseId,studentid) values (?,?) 在我的两种情况下,记录都被删除,并且插入了新的映射. 所以,我的问题是,如果我不想删除旧课程并为学生添加新课程我该如何实现,即我想保留旧的关系, 天气我必须以编程方式实现这一目标, 当我们将一个学生映射到多个课程时,会调用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> 等待回复…. 解决方法
我可能错了,但我认为这是正常的,当你进行插入时,Hibernate第一次删除关联表中的所有记录.
这就是原因:当使用x-to-many关联(基本上是通过Collection映射的关联)时,Hibernate的持久化上下文将基于Collection的标识符执行脏检查. 我们从CourseServiceBean类中获取mapCourseToStudents()方法: ... 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); ... 如果您确实希望避免Hibernate首先执行delete语句,则应该向Collection添加/删除项目,而不是分配新的Collection,并在映射数据中配置要级联的操作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |