Reputation: 3273
I am trying the Active Record pattern using Spring and Hibernate framework. Below is the description of this pattern:
An object carries both data and behavior. Much of this data is persistent and needs to be stored in a database. Active Record uses the most obvious approach, putting data access logic in the domain object. This way all people know how to read and write their data to and from the database.
So, I removed the traditional Service
class and moved its logic and the @Transactional
annotation to the entity class. But when I run my application again, the following exception was thrown.
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:133)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:454)
weibo.datasource.UserDao.save(UserDao.java:17)
weibo.domain.User.register(User.java:32)
weibo.web.UserController.register(UserController.java:29)
Source Code
The UserController
class:
@PostMapping("/users/register")
public String register(@RequestParam("username") String username,
@RequestParam("password") String password) {
User user = new User(userDao, username, password);
user.register();
return "redirect:/users/login";
}
The User
entity class:
@Entity
@Table(name="USERS")
@Transactional
public class User {
@Id
@GeneratedValue
private int id;
private String name;
private String password;
@Transient
private UserDao userDao;
public User() {}
public User(UserDao userDao, String username, String password) {
...
}
public void register() {
userDao.save(this);
}
}
The UserDao
class. No @Transactional
annotated.
public UserDao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void save(User user) {
sessionFactory.getCurrentSession().save(user);
}
Why?
UPDATE
As @cristianhh said, the @Transactional
annotation must be used in a Spring-Managed bean. However, the entity class is not.
Upvotes: 2
Views: 1852
Reputation: 138
No, while @Transactional
is managed by Spring, @Entity
is managed by Hibernate.
Hibernate beans are not managed by Spring and respectively not wrappable by the @Transactional
annotation.
You can however, use @Transactional
in the service/repository layer and wrap a function sending the entity's data access object (DAO).
Upvotes: 4