Issue: Cannot add Address object via User object inside a Spring Controller.
User and Address classes -> @Entity
User has a List<Address> with 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>
Everything is working fine. But I cannot make changes to the user object inside a @Controller.
When user object is getting change in @Controller level, there is no such Hibernate session involves with the object. Somehow the object is out of the hibernate context.
Error happens at .add(new Address("new street")); statement in @Controller.
Why it is prohibited to change an object inside a Controller which is received via Hibernate session?
The way I followed is incorrect? If not what have I done wrong?
--Spring 4, Hibernate 4
User has a List<Address>. When you fetch the user from the database rather then a list, hibernate inserts a proxy that handles the fetching of the addresses.
This proxy needs to have a session to be able to do anything. When you try to add an address you are outside the scope of the transactional annotation, thus there is no session.
Best way to get you going would be to add a method annotated with @Transactional in the UserService that adds an address.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With