Spring JPA Base Repository - PullRequest
       18

Spring JPA Base Repository

0 голосов
/ 11 марта 2019

Я создал собственный репозиторий для переопределения методов персистентности и попытался подключить его, как описано в Spring Docs .Я не получаю ошибок, все сущности и репозитории обнаруживаются при запуске, и когда я вызываю repo.saveAll (entity), постоянство работает нормально.Однако мой пользовательский код никогда не вызывается.Я добавил операторы журнала и даже добавил исключения RuntimeExceptions в мой код, просто чтобы посмотреть, выполняется ли он, но он определенно игнорируется.Какой шаг я пропустил?

@Configuration
@Profile("test")
@EnableJpaRepositories(repositoryBaseClass = SetClientInfoRepositoryImpl.class,
        basePackages = {"gov.penndot.hwy.apras.common.repository" }, 
        entityManagerFactoryRef = "serviceEntityManagerFactory", 
        transactionManagerRef = "serviceTransactionManager")
public class TestDatabaseConfig {

    @Bean(name = "serviceDataSource")
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:db;DB_CLOSE_DELAY=-1");
        dataSource.setUsername("sa");
        dataSource.setPassword("sa");

        return dataSource;
    }

    @Bean
    public EntityManagerFactoryBuilder entityManagerFactoryBuilder() {
        return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), new HashMap<String, Object>(), null);
    }

    @Bean(name = "serviceEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean serviceEntityManagerFactory(EntityManagerFactoryBuilder builder,
            @Qualifier("serviceDataSource") DataSource dataSource) {

        return builder
                .dataSource(dataSource)
                .packages("stuff")
                .persistenceUnit("service")
                .build();
    }

    @Bean(name = "serviceTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("serviceEntityManagerFactory") EntityManagerFactory serviceEntityManagerFactory) {
        return new JpaTransactionManager(serviceEntityManagerFactory);
    }

Репозиторий:

@NoRepositoryBean
    public class SetClientInfoRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> {
        private static final Logger log = LoggerFactory.getLogger(SetClientInfoRepositoryImpl.class);
        private final EntityManager em;

        public SetClientInfoRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) {
            super(entityInformation, entityManager);
            this.em = entityManager;
        }

        @Transactional
        @Override
        public <S extends T> S save(S entity) {
            setClientInfo();
            return super.save(entity);
        }

        @Transactional
        @Override
        public void deleteById(ID id) {
            setClientInfo();
            super.deleteById(id);
        }

        @Transactional
        @Override
        public void delete(T entity) {
            setClientInfo();
            super.delete(entity);
        }

        @Transactional
        @Override
        public void deleteAll(Iterable<? extends T> entities) {
            setClientInfo();
            super.deleteAll(entities);
        }

        @Transactional
        @Override
        public void deleteInBatch(Iterable<T> entities) {
            setClientInfo();
            super.deleteInBatch(entities);
        }

        @Transactional
        @Override
        public void deleteAll() {
            setClientInfo();
            super.deleteAll();
        }

        @Transactional
        @Override
        public void deleteAllInBatch() {
            setClientInfo();
            super.deleteAllInBatch();
        }

        @Transactional
        @Override
        public <S extends T> S saveAndFlush(S entity) {
            setClientInfo();
            return super.saveAndFlush(entity);
        }

        @Transactional
        @Override
        public <S extends T> List<S> saveAll(Iterable<S> entities) {
            setClientInfo();
            super.saveAll(entities);
            throw new RuntimeException("foo");
        }

        private void setClientInfo() {
            log.debug("Entering setClientInfo method");
            [stuff]
        }
    }

1 Ответ

0 голосов
/ 13 марта 2019

ОК, это довольно отчаянная идея, но стоит попробовать ...

Создать пользовательский интерфейс хранилища:

public interface SetClientInfoRepository<T, ID> extends JpaRepository<T, ID> {
}

Реализовать этот интерфейс хранилища с помощью своей пользовательской базырепозиторий:

public class SetClientInfoRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements SetClientInfoRepository<T, ID> {
}

... и, наконец, расширить этот интерфейс с помощью интерфейсов репозитория вместо JpaRepository

Таким образом Spring должен создать репозиторий.прокси из вашей реализации, потому что нет других классов, которые он мог бы использовать.Кроме того, если по какой-либо причине он не может создать репозитории, вы получите более информативное исключение при запуске.

Использование собственного интерфейса репозитория само по себе неплохо, поскольку всегда есть хорошие шансычто позже вы захотите добавить некоторые общие пользовательские методы в свои репозитории, и тогда это пригодится.

...