Estoy probando el patrón Active Record usando el marco Spring e Hibernate. A continuación se muestra la descripción de este patrón:
Un objeto transporta tanto datos como comportamiento. Gran parte de estos datos son persistentes y deben almacenarse en una base de datos. Active Record utiliza el enfoque más obvio, colocando la lógica de acceso a datos en el objeto de dominio. De esta manera, todas las personas saben cómo leer y escribir sus datos hacia y desde la base de datos.
Entonces, eliminé la clase Service tradicional y moví su lógica y la anotación @Transactional a la clase de entidad. Pero cuando ejecuto mi aplicación nuevamente, se lanzó la siguiente excepción.
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)Código fuente
La clase UserController :
@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"; } La clase de entidad User :
@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); } } La clase UserDao . No @Transactional anotado.
public UserDao(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void save(User user) { sessionFactory.getCurrentSession().save(user); }¿Por qué?
ACTUALIZAR
Como dijo @cristianhh, la anotación @Transactional debe usarse en un bean administrado por Spring . Sin embargo, la clase de entidad no lo es.
No, mientras @Transactional es administrado por Spring, @Entity es administrado por Hibernate.
Los beans de Hibernate no son administrados por Spring y, respectivamente, no pueden ser envueltos por la anotación @Transactional .
Sin embargo, puede usar @Transactional en la capa de servicio/repositorio y ajustar una función que envíe el objeto de acceso a datos (DAO) de la entidad.