LoginSignup
0
2

More than 5 years have passed since last update.

[Java][Spring] Spring DataのRepositoryをインスタンス化する際にHibernateのフィルタを有効にしようとして失敗した記録

Last updated at Posted at 2017-04-20

動機

Hibernate 3でマルチテナントをしようとしました。

各テーブルにテナントを区別するためのSystemId列を付けました。

SystemId列を検索条件に付与するHibernateフィルタをJPAエンティティに付けました。

失敗の記録

自前のRepositoryファクトリを使うようにする

Configurationに以下のようなアノテーションをつけて、自前のRepositoryファクトリを使うようにしました。

@EnableJpaRepositories(basePackages = "com.example.dataaccess.repositories",
        repositoryFactoryBeanClass = PrimaryRepositoryFactoryBean.class)

作成したRepositoryファクトリ

PrimaryRepositoryFactoryBean.class
public class PrimaryRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {

    @Autowired // この子がSystemIdを持っている
    private CurrentAppUserDetailsProvider currentAppUserDetailsProvider;

    @Override // RepositoryFactoryを返します
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new MyRepositoryFactory(entityManager, currentAppUserDetailsProvider);
    }

    private static class MyRepositoryFactory<E, I extends Serializable> extends JpaRepositoryFactory {

        private final EntityManager entityManager;
        private final CurrentAppUserDetailsProvider currentAppUserDetailsProvider;

        public MyRepositoryFactory(EntityManager entityManager,
                CurrentAppUserDetailsProvider currentAppUserDetailsProvider) {
            super(entityManager);
            this.entityManager = entityManager;
            this.currentAppUserDetailsProvider = currentAppUserDetailsProvider;
        }

        @Override
        protected Object getTargetRepository(RepositoryMetadata metadata) {
            Object repository = super.getTargetRepository(metadata);

            SessionFactory sessionFactory = entityManager.getEntityManagerFactory().unwrap(SessionFactory.class);

            Session session = sessionFactory.getCurrentSession(); // 例外発生!!

            session.enableFilter("SYSTEM_ID_FILTER")
                    .setParameter("systemId", getSystemId());

            return repository;
        }

        private int getSystemId() {
            return currentAppUserDetailsProvider
                    .getCurrentAppUserDetails()
                    .getSystemId();
        }

    }
}

失敗の内容

Repositoryをインスタンス化する時点では、トランザクション始まってないからSession無いよーーー。

当たり前だよねーーー。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2