Hibernate не сохраняет коллекцию значений - PullRequest
4 голосов
/ 31 августа 2009

Хорошо, я использовал Hibernate в нескольких проектах сейчас, но я не изучал его тонкости, прежде чем использовать его. Я начал с просмотра кодов, использующих аннотации JPA и интегрированных с Spring, и все работало хорошо. Но теперь, когда я хочу преподавать базовый Hibernate для своих учеников, и я нахожусь в процессе создания примера и использования учебного руководства по главе 1, у меня возникла проблема с сохранением набора значений коллекции в одном постоянном классе.

Вот постоянный класс ...

public class Student {
    private Long id;
    private String firstName;
    private String lastName;
    private Set<Course> courses = new HashSet<Course>();
    private Set<String> contactDetails = new HashSet<String>();

    //getters and setters
}

Файл сопоставления ...

<hibernate-mapping package="com.phoenixone.school.model">
    <class name="Student" table="student">
        <id name="id" column="studentId">
           <generator class="native" />
        </id>

        <property name="firstName" />
        <property name="lastName" />

        <set name="courses" table="student_course" lazy="false">
            <key column="studentId" />
           <many-to-many column="courseId" class="Course" />
        </set>

        <set name="contactDetails" table="contactDetails">
            <key column="studentId" />
            <element type="string" column="contactDetail" />
        </set>
    </class>
</hibernate-mapping>

DAO (спасительная часть)

public class StudentDaoHibernate {
    public void save(Student student){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        session.save(student);
        session.getTransaction().commit();
    }
}

Тестирующая часть ...

public class TestStudentDaoHibernate {
    public static void main(String[] args) {
        CourseDaoHibernate courseDao = new CourseDaoHibernate();

        Course c1 = new Course();
        c1.setCourseCode("CWD");
        c1.setCourseName("Web Dev");
        courseDao.save(c1);

        Set<Course> courses = new HashSet<Course>();
        courses.add(c1);

        Student student = new Student();
        student.setFirstName("Bob");
        student.setLastName("Santos");
        student.setCourses(courses);
        student.getContactDetails().add("123456789");                 

                StudentDaoHibernate dao = new StudentDaoHibernate();
        dao.save(student);
    }
}

Когда я выполняю эти строки кода ...

Session session = HibernateUtil.getSessionFactory().getCurrentSession()
session.beginTransaction();
Student student = (Student)session.createCriteria(Student.class)
             .add(Restrictions.eq("id", new Long(1))).uniqueResult();
System.out.println("First Name: " + student.getFirstName());
System.out.println("Last Name: " + student.getLastName());

System.out.println("Courses enrolled with...");
for(Course c:student.getCourses()){
    System.out.println(c.getCourseName());
}

System.out.println("Contact details...");
for(String s:student.getContactDetails()){
    System.out.println(s);
}

Что я получаю, это ...

Имя: Боб
Фамилия: Сантос
Курсы, зачисленные с ...
Веб-разработчик
Контактная информация ...

Что приводит меня к выводу, что строка "123456789" не была сохранена. Как вы думаете, в чем проблема с моим кодом? Спасибо!

Ответы [ 3 ]

5 голосов
/ 31 августа 2009

Вам нужно добавить каскадный атрибут к вашим элементам набора для курсов и contactDetails. Это определяет, какие операции, выполняемые над родительским объектом, будут применены к дочернему объекту. Значением по умолчанию является none, поэтому при сохранении ученика ни один из дочерних элементов в наборах не был сохранен.

Добавление cascade = "all, delete-orphan" будет охватывать все операции, но вы можете быть более строгими, если хотите. Подробнее см. здесь в справочнике Hibernate 4.3.

1 голос
/ 05 июля 2012

После session.save(student); попробуйте добавить session.flush();

0 голосов
/ 31 августа 2009

Я бы порекомендовал создать класс Contract и использовать его вместо String. Это лучшая абстракция, и свидетельство того, что Hibernate отлично справился с вашим классом Course, говорит о том, что оно будет хорошо работать и с Contract.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...