Hibernate - 懒得初始化一个角色集合 - 无法初始化代理 - 没有Session

时间:2015-02-01 20:58:03

标签: spring hibernate dao

问题:无法通过Address内的User对象添加Controller对象。

UserAddress类 - > @Entity

UserList<Address> FetchType=LAZY

@Repository
public class UserDao{
    @Autowired
    private SessionFactory sessionFactory;
    ...
    public User get(String username) {
        Session session = sessionFactory.getCurrentSession();
        return (User)session.get(User.class, username);
    }
    ...
    public void update(User user){
        Session session = sessionFactory.getCurrentSession();
        session.saveOrUpdate(user);
    }
    ...
}


@Service
@Transnational
public class UserService{
    @AutoWired
    private UserDao userDao;
    ...

    @Transactional(readOnly = true)
    public User get(String username) {
        Session session = sessionFactory.getCurrentSession();
        return (User)session.get(User.class, username);
    }

    public void update(User user){
        userDao.update(user);
    } 
    ...
}

@Controller
public class UserController{
    @AutoWired
    private UserService userService;
    ....
    public String update(){
        User user = userService.get("user0001");
        user.getAddressList.add(new Address("new street"));
        return "update";
    }
}

Spring.xml

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:jdbc.properties</value>
    </property>
</bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driverClassName}" />
    <property name="jdbcUrl" value="${jdbc.url}" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dataSource"/>
    </property>
    <property name="packagesToScan" value="com.entity" />
    <property name="hibernateProperties">
       <props>
         <prop key="hibernate.dialect">${hibernate.dialect}</prop>
         <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
       </props>
    </property> 
</bean>

一切都很好。但我无法对user内的@Controller对象进行更改。

user对象在@Controller级别进行更改时,对象中不存在此类Hibernate会话。不知何故,该对象超出了休眠上下文。

.add(new Address("new street"));中的@Controller语句发生错误。

为什么禁止更改通过Hibernate会话接收的Controller内的对象?

我遵循的方式不正确?如果不是我做错了什么?

- Spring 4,Hibernate 4

1 个答案:

答案 0 :(得分:3)

User有一个List<Address>。当您从数据库而不是列表中获取用户时,hibernate会插入一个代理来处理提取地址。

此代理需要有一个会话才能执行任何操作。当您尝试添加地址时,您不在事务注释的范围内,因此没有会​​话。

让您前进的最佳方式是在@Transactional中添加一个使用UserService注释的方法,以添加地址。