简体   繁体   English

Spring JPA基础存储库

[英]Spring JPA Base Repository

I have created a custom repository to override persistence methods and tried to wire it up as described in the spring docs . 我创建了一个自定义存储库以覆盖持久性方法,并尝试按照spring docs中的说明进行连接 I receive no errors, all entities and repositories are found on startup, and when I call repo.saveAll(entities), persistence works normally. 我没有收到任何错误,所有实体和存储库都在启动时找到,并且当我调用repo.saveAll(entities)时,持久性正常工作。 However, my custom code is never called. 但是,从未调用我的自定义代码。 I have added log statements and even thrown RuntimeExceptions in my code, just to see if it's being executed, but it's definitely being ignored. 我在代码中添加了日志语句,甚至引发了RuntimeExceptions,只是为了查看它是否正在执行,但是肯定会忽略它。 What step have I missed? 我错过了哪一步?

@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);
    }

Repository: 库:

@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]
        }
    }

OK, this is quite a desperate idea, but it could worth a try... 好的,这是一个绝望的主意,但值得一试...

Create a custom repository interface: 创建一个定制的存储库界面:

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

Implement this repository interface by your custom base repository: 通过您的定制基础存储库实现此存储库接口:

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

... and finally extend this interface by your repository interfaces instead of JpaRepository ...最后通过您的存储库接口而不是JpaRepository扩展此接口

In this way Spring has to create the repository-proxies from your implementation because there are no other classes it could use. 通过这种方式,Spring 必须从您的实现中创建存储库代理,因为它无法使用其他任何类。 Also, if it cannot create the repositories because of any reason, you will get a more informative exception during startup. 另外,如果由于某种原因它不能创建存储库,则在启动过程中会得到更多信息。

Using the custom repository interface is not a bad thing in its own, because there is always a good chance that you want to add some common custom methods to your repositories later and then it will come handy. 使用定制存储库接口本身并不是一件坏事,因为您总是有很大的机会希望以后向存储库中添加一些通用的定制方法,这样会很方便。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM