如何在hibernate / spring中更新多对多集合(延迟加载)?

时间:2015-03-27 19:54:29

标签: spring hibernate orm hibernate-mapping

我有三个表和两个类。两个表/类之间存在多对多的关系
OYS_USER - >多对多与'oys_lesson'
OYS_LESSON - >多对多与'oys_user'
OYS_LESSON_STUDENT - >关系

User.class

@ManyToMany(cascade= CascadeType.ALL,fetch=FetchType.LAZY)
@JoinTable(name="oys_lesson_student", 
    joinColumns = {  @JoinColumn(name="student_id",referencedColumnName="id")},
    inverseJoinColumns = {@JoinColumn(name="lesson_id",referencedColumnName="id") })
@Fetch(FetchMode.SUBSELECT)
private Set<Lesson> studentLessons;
Lesson.class

中的

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinTable(name = "oys_lesson_student", joinColumns = { @JoinColumn(name = "lesson_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "student_id", referencedColumnName = "id") })
@Fetch(FetchMode.SUBSELECT)
private Set<User> lessonStudents;

我使用以下代码更新了集合:

@Override
public void addLessonToStudent(Lesson lesson) {
        // TODO Auto-generated method stub
    String username = SecurityContextHolder.getContext()
            .getAuthentication().getName();
            Criteria criteria = openSession().createCriteria(User.class)
                    .add(Restrictions.eq("username", username));
            User user=(User) criteria.uniqueResult();
            log.info("'"+lesson.getLessonName()+"' lesson added to '"+user.getUsername()+"'");
            /*user.getStudentLessons().add(lesson);
            updateUser(user);
            */
            lesson.getLessonStudents().add(user);
            updateLesson(lesson);
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

}
@Override
public void updateLesson(Lesson lesson) {
    log.info(lesson.getLessonName()+" updated.");
    openSession().update(lesson);
}

当我将当前用户添加到课程集合(或课程到当前用户的集合)时 更新/插入查询未出现在休眠统计信息(console-log)中 因此,记录不能添加到任何集合中 基本上,我想在很多到很多集合中添加新对象。我做错了什么?

  • 我使用hibernate 4.3.5.Final(摆脱延迟加载异常)
  • 我使用org.springframework.orm.hibernate4.support.OpenSessionInViewFilter来摆脱延迟加载异常。)
  • 我尝试使用FetchType.JOIN.But的CascadeType.EAGER没有更改results.update / insert查询没有出现在hibernate statistics(console-log)中。
  • 我在application-context.xml(spring-hibernate-configuration)中使用hibernate的以下属性:

        <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.generate_statistics">true</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.cache.use_query_cache">true</prop>
            <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory
            </prop>
            <prop key="hibernate.enable_lazy_load_no_trans">true</prop>
            <prop key="use_sql_comments">true</prop>
            <prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
            <prop key="hibernate.connection.autocommit">true</prop>
            <prop key="net.sf.ehcache.configurationResourceName">/myehcache.xml</prop>
        </props>
    </property>
    
  • 和spring txManager:

            <!-- Enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven transaction-manager="txManager" />
    
    <!-- Transaction Manager is defined -->
    <bean id="txManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="SessionFactory" />
    </bean>
    

    我使用spring / security,hibernate 4.3.5.Final,jpa2.1,jsf2.2。提前致谢。

1 个答案:

答案 0 :(得分:0)

你快到了。

首先,您需要确定您的关联的哪个网站是“控制”的。是用户还是教训。并且你只在其中一个上定义连接表,例如: - 让用户保持原样 - 在课程上你改变了

@ManyToMany(mappedBy="studentLessons" ...)

然后,您需要手动将关联添加到关系的两个站点(实际上通常需要添加到负责映射的站点)。

所以

user.getUserLesseson().add(lesson);
lesson.getLessonStudents().add(user);

如果两者都在事务内发出,则会导致插入