2017-03-16 6 views
2

私は、SpringとHibernateフレームワークを使ってActive Recordパターンを試しています。以下はこのパターンの説明です:@Transactionalアノテーションをエンティティクラスに配置できますか?

オブジェクトはデータと動作の両方を持ちます。このデータの多くは永続的であり、データベースに格納する必要があります。 Active Recordは最も明白なアプローチを採用し、データアクセスロジックをドメインオブジェクトに入れます。このようにして、すべての人がデータベースとの間でデータを読み書きする方法を知っています。

だから、私は伝統的なServiceクラスを削除し、そのロジックとエンティティクラスに@Transactional注釈を移動しました。しかし、私が再びアプリケーションを実行すると、次の例外がスローされました。

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クラス:

@PostMapping("https://stackoverflow.com/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エンティティクラス:

@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クラス。いいえ@Transactional注釈。

public UserDao(SessionFactory sessionFactory) { 
    this.sessionFactory = sessionFactory; 
} 
public void save(User user) { 
    sessionFactory.getCurrentSession().save(user); 
} 

なぜですか?

UPDATE

@cristianhhは@TransactionalアノテーションがSpring管理豆に使用されなければならない、と述べたように。しかし、エンティティクラスはそうではありません。

+0

@TransactionalはあなたのUserDaoクラスになければなりません。 –

+0

@EssexBoy従来の 'Controller-Service-Dao'実装では、このアノテーションを' Dao'クラスではなく 'Service'クラスに追加する方がよいでしょう。 http://stackoverflow.com/questions/1079114/where-does-the-transactional-annotation-belong – walsh

答えて

4

いいえ、@TransactionalはSpringによって管理されますが、@EntityはHibernateによって管理されます。

Hibernate BeanはSpringによって管理されず、それぞれ@Transactionalアノテーションによってラップ可能ではありません。

ただし、サービス/リポジトリレイヤで@Transactionalを使用し、エンティティのデータアクセスオブジェクト(DAO)を送信する関数をラップすることはできます。

+0

ああ、そうです。ありがとう。 – walsh

+0

別の質問:私は注釈を 'UserController'クラスに移しましたが、同じ例外がスローされました。どうして? – walsh

+0

もちろん、それは良い習慣ではありません、私はちょうどソースコードの言葉の理由を知りたいです。 – walsh

関連する問題