我通过注释在hibernate中进行双向多对多映射存在问题。
设置为Student:StudentCertification,具有N:N关系。 @ManyToMany(mappedby = ...)注释用于逆非持有方(StudentCertification),并在所有者方(学生)上使用@ManyToMany和@JoinTable注释。
问题是,当通过仅保存非拥有方存储记录时,不填充映射表(Student_StudentCertification),而填充拥有和非拥有方的表(参见休眠日志2)。因此,数据库中没有N:N关系,只有两个表没有相关的Student和StudentCertification存在。 注意,创建了所有三个提到的表(请参阅hibernate日志1)。 保存拥有方对象(学生)时,没有问题。所有表格都已填满。 它表示mapby参数不能正常工作,并且不指向所有者端属性,其中N:N关系的描述由注释定义。 代码使用jUnit测试来保存10个非拥有对象STUDENTCERTIFICATION,每个对象都添加了10个不同的学生(参见jUnit代码):
你能帮帮我,为什么mappedby参数还不够?或者问题出在哪里呢? 感谢。
拥有学生:
@Entity
@Table(name = "STUDENT")
public class Student {
//== VARIABLE INSTANCE FIELDS ==============================================
@Id
@GeneratedValue
@Column(name = "STUDENT_ID_COLUMN")
private int student_id;
@Column(name = "NAME_COLUMN", nullable = false)
private String student_name;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "STUDENT_STUDENTCERTIFICATION",
joinColumns = {@JoinColumn
(name = "STU_ID", referencedColumnName = "STUDENT_ID_COLUMN")},
inverseJoinColumns = {@JoinColumn
(name = "CER_ID", referencedColumnName = "CERTIFICATION_ID_COLUMN")} )
private List<StudentCertification> _listOfCertifications
= new ArrayList<StudentCertification>();
//== INSTANCE GETTERS AND SETTERS ==========================================
// . . . the rest of all getter and setters
}
非自主方学生:
@Entity
@Table(name = "STUDENTCERTIFICATION")
public class StudentCertification {
//== VARIABLE INSTANCE FIELDS ==============================================
@Id
@GeneratedValue
@Column(name = "CERTIFICATION_ID_COLUMN")
private int _certification_id;
@Column(name = "CERTIFICATION_NAME_COLUMN", nullable = false)
private String _certification_name;
@ManyToMany(cascade = CascadeType.All, mappedBy = "_listOfCertifications")
private List<Student> _listOfStudents;
//== INSTANCE GETTERS AND SETTERS ==========================================
/**
* @return the _certification_id
*/
public int get_certification_id() {
return _certification_id;
}
// . . . the rest of all getter and setters
}
jUnit测试:
public class TestHibernateManyToMany {
//== VARIABLE INSTANCE FIELDS ==============================================
/** The list of student and certification */
private List<Student> listSuccStud = new ArrayList<Student>();
private List<StudentCertification> listSuccCert = new ArrayList<StudentCertification>();
/**
* Sets the testing fixture up.
*
* @throws Exception the exception
*/
@Before
public void setUp() throws Exception {
//code for creation of list of 10 students and list of 10 certifications
}
//== TESTING CLASSES AND METHODS ===========================================
/**
* Test many to many, the given certification is related to the 10 students and then is saved
*/
@Test
public void testManyToManyBidir() {
// assign all students for each certification
for (StudentCertification cer : listSuccCert) {
cer.set_listOfStudents(listSuccStud);
Main.safeTheObjectIntoDatabase(cer); //saving certification
}
}
保存非拥有方模型的主要代码:
public class Main {
//== TESTING CLASSES AND METHODS ===========================================
/**
* Test method to save the object into database.
*
* @param object the object
*/
public static void safeTheObjectIntoDatabase(Object object) {
{SessionFactory sessionFactory = HibernateUtil.getSessionFactory();//create factory
Session session = sessionFactory.openSession();
Transaction transaction = null;
try{
transaction = session.beginTransaction();
session.save(object);
transaction.commit();
}
catch (Exception e)
{
if(transaction != null)
{
transaction.rollback();
}
throw new RuntimeException("Pri volani SQL nastala chyba", e);
}
finally
{
session.close();
}
}//block session factory
}
休眠日志1:表创建
Hibernate: alter table STUDENT_STUDENTCERTIFICATION drop foreign key FK_j6up3gxynxgvtfax9105f0vbs
Hibernate: alter table STUDENT_STUDENTCERTIFICATION drop foreign key FK_tfdgl5fmkt2t1dae8p3fwpal5
Hibernate: drop table if exists STUDENT
Hibernate: drop table if exists STUDENTCERTIFICATION
Hibernate: drop table if exists STUDENT_STUDENTCERTIFICATION
Hibernate: create table STUDENT (STUDENT_ID_COLUMN integer not null auto_increment, NAME_COLUMN varchar(255) not null, primary key (STUDENT_ID_COLUMN))
Hibernate: create table STUDENTCERTIFICATION (CERTIFICATION_ID_COLUMN integer not null auto_increment, CERTIFICATION_NAME_COLUMN varchar(255) not null, primary key (CERTIFICATION_ID_COLUMN))
Hibernate: create table STUDENT_STUDENTCERTIFICATION (STU_ID integer not null, CER_ID integer not null)
Hibernate: alter table STUDENT_STUDENTCERTIFICATION add constraint FK_j6up3gxynxgvtfax9105f0vbs foreign key (CER_ID) references STUDENTCERTIFICATION (CERTIFICATION_ID_COLUMN)
Hibernate: alter table STUDENT_STUDENTCERTIFICATION add constraint FK_tfdgl5fmkt2t1dae8p3fwpal5 foreign key (STU_ID) references STUDENT (STUDENT_ID_COLUMN)
Hibernate log 2:表插入和更新,!!!没有映射表插入!!!
Hibernate: insert into STUDENTCERTIFICATION (CERTIFICATION_NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENT (NAME_COLUMN) values (?)
Hibernate: insert into STUDENTCERTIFICATION (CERTIFICATION_NAME_COLUMN) values (?)
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
Hibernate: insert into STUDENTCERTIFICATION (CERTIFICATION_NAME_COLUMN) values (?)
Hibernate: update STUDENT set NAME_COLUMN=? where STUDENT_ID_COLUMN=?
... the similar pattern of code, !!! no mapping table STUDENT_STUDENTCERTIFICATION insert !!!