我可以将 @Transactional 注释放置到实体 class 吗?
Can I place the @Transactional annotation to an entity class?
我正在尝试使用 Spring 和 Hibernate 框架的 Active Record 模式。下面是这个模式的描述:
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.
因此,我删除了传统的 Service
class 并将其逻辑和 @Transactional
注释移至实体 class。但是当我再次 运行 我的应用程序时,抛出了以下异常。
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)
源代码
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";
}
User
实体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);
}
}
UserDao
class。没有 @Transactional
注释。
public UserDao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void save(User user) {
sessionFactory.getCurrentSession().save(user);
}
为什么?
更新
正如@cristianhh 所说,@Transactional
注释必须在 Spring-Managed bean 中使用。但是,实体 class 不是。
不,@Transactional
由 Spring 管理,@Entity
由 Hibernate 管理。
Hibernate bean 不由 Spring 管理,并且分别不能由 @Transactional
注释包装。
但是,您可以在 service/repository 层中使用 @Transactional
并包装一个发送实体数据访问对象 (DAO) 的函数。
我正在尝试使用 Spring 和 Hibernate 框架的 Active Record 模式。下面是这个模式的描述:
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.
因此,我删除了传统的 Service
class 并将其逻辑和 @Transactional
注释移至实体 class。但是当我再次 运行 我的应用程序时,抛出了以下异常。
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)
源代码
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";
}
User
实体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);
}
}
UserDao
class。没有 @Transactional
注释。
public UserDao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void save(User user) {
sessionFactory.getCurrentSession().save(user);
}
为什么?
更新
正如@cristianhh 所说,@Transactional
注释必须在 Spring-Managed bean 中使用。但是,实体 class 不是。
不,@Transactional
由 Spring 管理,@Entity
由 Hibernate 管理。
Hibernate bean 不由 Spring 管理,并且分别不能由 @Transactional
注释包装。
但是,您可以在 service/repository 层中使用 @Transactional
并包装一个发送实体数据访问对象 (DAO) 的函数。