2009-08-31 4 views
3

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

Вот упорная класс ...

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> 

дао (экономия часть)

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

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

Имя: Bob
Фамилия: Santos
курсы зачисленных. ..
Web Dev
Контактная информация ...

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

+0

3 лет, и нет ответа. У меня такая же проблема ... – Stewart

ответ

0

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

+0

Спасибо, duffymo за предложение. Я бы тоже сделал класс Contact, если бы не следующий учебник.: | У вас есть идеи, почему это не сохранилось? – 2009-08-31 09:55:14

+0

Не сейчас, но, возможно, я попробую это сегодня вечером и вернусь к вам. – duffymo

+0

Возвращайся. Благодаря! – 2009-09-01 14:52:02

4

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

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

+0

Привет, Марк! У меня не было проблем с сохранением Set только с помощью Set , который, как я думаю, потому что это набор значений, а не набор объектов. Я добавил cascade = "all" в оба файла в файл сопоставления, как вы предлагали. К сожалению, у меня был такой же результат. – 2009-08-31 10:22:20

+0

Ссылка мертва x_X – naXa

+0

Исправлена ​​неработающая ссылка и добавлена ​​ссылка на v4.3 – Mark

1

После session.save(student); попытки добавления session.flush();

+0

Я решил проблему со связью «многие-ко-многим», неправильно очищенной от спящего режима. – JFL

Смежные вопросы