Java – JPA, many to many relationship, delete all previous relationships and enter new relationships

Here, I am trying the many to many relationship in JPA. I have created tables "tblcourse" and "tblstudent". Students can register for many courses,

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

The JPA representation of the above relationship is as follows. This is studententity Java code,

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

This is courseentity Java code,

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

Now, when I try to pass studententity When Java is inserted into the course, the SQL query triggered at the back end is

delete 
    from
        tblcourseStudent 
    where
        studentid=?

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

insert 
    into
        tblcourseStudent
        (studentid,?)

And when I try to pass courseentity When Java is inserted into a student, the SQL query triggered is as follows,

delete 
    from
        tblcourseStudent 
    where
        courseId=?

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

In both cases, the record is deleted and a new mapping is inserted Therefore, if I insert a course for a student, I will first delete all previous courses for the student from the third table and enter a new course,

So my question is, if I don't want to delete the old course and add a new course for students, how can I do it, that is, I want to keep the old relationship,

Weather, I have to achieve this goal programmatically, or I change the comment and wait for a reply

When we map a student to multiple courses, we call studentservicebean Code written in Java and the "mapstudenttocourses" method

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

This is to map a course to multiple students and their courseservicebean Java code

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

This is my persistence XML file,

<?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>

Waiting for reply

Solution

I may be wrong, but I think this is normal. When you insert, hibernate deletes all records in the associated table for the first time

This is why: when using x-to-many associations (basically associations mapped through the collection), hibernate's persistence context will perform dirty checks based on the identifier of the collection

We get the mapcoursetostudents() method from the courseservicebean class:

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

If you really want to avoid hibernate from executing delete statements first, you should add / delete items to the collection instead of assigning a new collection, and configure the operations to cascade in the mapping data

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>