Объекты не отсканированы - PullRequest
0 голосов
/ 26 июня 2018

У меня есть проект Maven, который представляет уровень данных сервера единого входа (SSO).Другие клиентские приложения должны использовать его для аутентификации и авторизации пользователя.

Это .jar архив, который должен использоваться другим REST проектом, также проектом Maven.

ОбаПроекты на основе Spring Boot 2.

Этот проект должен иметь некоторые интеграционные тесты с базами данных H2 и MySQL.

Поскольку это библиотека, она не запускается сама по себе.Но у него есть некоторые интеграционные тесты, которые должны быть выполнены.Поэтому класс main отсутствует.

Команда, используемая для построения и выполнения тестов, mvn clean install -Denv="test"

Мое дерево исходного кода выглядит следующим образом:

├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── thalasoft
    │   │           └── userdata
    │   │               ├── config
    │   │               │   ├── DatabaseConfiguration.java
    │   │               │   ├── JpaService.java
    │   │               │   └── properties
    │   │               │       ├── AbstractDatabaseProperties.java
    │   │               │       ├── DatabaseH2TestProperties.java
    │   │               │       ├── DatabaseMySQLAcceptanceProperties.java
    │   │               │       ├── DatabaseMySQLPreProdProperties.java
    │   │               │       ├── DatabaseMySQLProdProperties.java
    │   │               │       ├── DatabaseMySQLTestProperties.java
    │   │               │       ├── DatabaseOraclePreProdProperties.java
    │   │               │       ├── DatabaseOracleProdProperties.java
    │   │               │       ├── DatabaseOracleTestProperties.java
    │   │               │       ├── DatabaseProperties.java
    │   │               │       └── PropertyNames.java
    │   │               ├── dialect
    │   │               │   ├── CustomMySQL5InnoDBDialect.java
    │   │               │   └── CustomOracle10gDialect.java
    │   │               ├── exception
    │   │               │   ├── CannotDeleteEntityException.java
    │   │               │   ├── EnrichableException.java
    │   │               │   ├── EntityAlreadyExistsException.java
    │   │               │   ├── EntityNotFoundException.java
    │   │               │   └── NoEntitiesFoundException.java
    │   │               ├── jpa
    │   │               │   ├── domain
    │   │               │   │   ├── AbstractEntity.java
    │   │               │   │   ├── EmailAddress.java
    │   │               │   │   ├── User.java
    │   │               │   │   └── UserRole.java
    │   │               │   └── repository
    │   │               │       ├── GenericRepositoryImpl.java
    │   │               │       ├── GenericRepository.java
    │   │               │       ├── UserRepositoryCustom.java
    │   │               │       ├── UserRepositoryImpl.java
    │   │               │       ├── UserRepository.java
    │   │               │       ├── UserRoleRepositoryCustom.java
    │   │               │       ├── UserRoleRepositoryImpl.java
    │   │               │       └── UserRoleRepository.java
    │   │               └── service
    │   │                   ├── UserRoleServiceImpl.java
    │   │                   ├── UserRoleService.java
    │   │                   ├── UserServiceImpl.java
    │   │                   └── UserService.java
    │   └── resources
    │       ├── application.properties
    │       └── custom
    │           └── typedef.hbm.xml
    └── test
        ├── java
        │   └── com
        │       └── thalasoft
        │           └── userdata
        │               ├── assertion
        │               │   └── UserAssert.java
        │               ├── it
        │               │   ├── jpa
        │               │   │   ├── AbstractRepositoryTest.java
        │               │   │   ├── UserRepositoryTest.java
        │               │   │   └── UserRoleRepositoryTest.java
        │               │   └── service
        │               │       ├── AbstractServiceTest.java
        │               │       └── UserServiceTest.java
        │               └── ut
        │                   ├── AbstractRepositoryTest.java
        │                   └── UserRepositoryTest.java
        └── resources
            ├── h2
            │   └── data-source-test.properties
            ├── mysql
            │   ├── clean-up-before-each-test.sql
            │   └── data-source-test.properties
            └── oracle
                ├── data-source-preprod.properties
                └── data-source-test.properties

DatabaseH2TestProperties загружается благодаря пользовательской аннотации, определенной в другом проекте панели инструментов Maven:

@EnvTest
@DbH2
@Configuration
@PropertySource({ "classpath:h2/data-source-test.properties" })
public class DatabaseH2TestProperties extends AbstractDatabaseProperties {

  private static Logger logger = LoggerFactory.getLogger(DatabaseH2TestProperties.class);

  public DatabaseH2TestProperties() {
    logger.debug("===========>> Loading the classpath h2/data-source-test.properties file");
  }
}

Файл data-source-test.properties содержит:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.datasource.driver-class-name=net.sf.log4jdbc.DriverSpy
spring.datasource.url=jdbc:log4jdbc:h2:file:./target/useraccounttest
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true

Все тесты основаныв классе:

@ContextConfiguration(classes = { DatabaseConfiguration.class })
@RunWith(SpringRunner.class)
@Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts = { "classpath:mysql/clean-up-before-each-test.sql" })
public abstract class AbstractRepositoryTest {
}

В этом классе мне интересно, не стоит ли вместо этого использовать @SpringBootTest(classes = { DatabaseConfiguration.class }).

И конфигурация выполняется с помощью:

@EnableAutoConfiguration
@ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.userdata" })
public class DatabaseConfiguration {
}

Соединение с базой данных H2 установлено успешно:

02:23:56.299 [main] DEBUG jdbc.audit - 100. Connection.getMetaData() returned dbMeta74: conn99: url=jdbc:h2:file:./target/useraccounttest user=SA  com.zaxxer.hikari.pool.ProxyConnection.getMetaData(ProxyConnection.java:361)
02:23:56.299 [main] DEBUG org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator - Database ->
       name : H2
    version : 1.4.197 (2018-03-18)
      major : 1
      minor : 4
02:23:56.299 [main] DEBUG org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator - Driver ->
       name : H2 JDBC Driver
    version : 1.4.197 (2018-03-18)
      major : 1
      minor : 4
02:23:56.299 [main] DEBUG org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator - JDBC version : 4.0
02:23:56.299 [main] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
02:23:56.305 [main] DEBUG jdbc.audit - 100. Connection.clearWarnings() returned   com.zaxxer.hikari.pool.ProxyConnection.close(ProxyConnection.java:250)

Но я получаю исключение.

Что говорит консольный журнал:

02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'com.thalasoft.userdata.config.JpaService'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'com.thalasoft.userdata.config.properties.DatabaseH2TestProperties'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'com.thalasoft.userdata.jpa.repository.GenericRepositoryImpl'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'com.thalasoft.userdata.jpa.repository.GenericRepositoryImpl'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
02:23:56.340 [main] WARN org.springframework.context.support.GenericApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.thalasoft.userdata.jpa.repository.GenericRepositoryImpl' defined in file [/home/stephane/dev/java/projects/user-data/target/classes/com/thalasoft/userdata/jpa/repository/GenericRepositoryImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Class<?>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

Действительно,У меня есть собственный универсальный репозиторий:

@Repository
@Transactional
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
        implements GenericRepository<T, ID> {

    private EntityManager entityManager;

    private final Class<T> domainClass;

    public GenericRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
        super(domainClass, entityManager);
        this.entityManager = entityManager;
        this.domainClass = domainClass;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }
}

@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {

  public EntityManager getEntityManager();
}

И он используется как:

public interface UserRepository extends GenericRepository<User, Long>, UserRepositoryCustom {
}

public interface UserRepositoryCustom {

    public User deleteByUserId(Long id) throws EntityNotFoundException;

}

public class UserRepositoryImpl implements UserRepositoryCustom {

    @Autowired
    private UserRepository userRepository;

}

Такое ощущение, что класс домена не может быть найден для универсального типа.

1 Ответ

0 голосов
/ 26 июня 2018

Ваш интерфейс GenericRepository и класс GenericRepositoryImpl соответствуют шаблону для фрагмента репозитория, используемого в пользовательских реализациях репозитория в Spring Data JPA , поэтому я предполагаю, что Spring Data пытается создать его экземпляр для использования в качественапример.Я бы попробовал переименовать GenericRepositoryImpl в AbstractGenericRepository или сделать его абстрактным классом или, возможно, и тем, и другим.Вы также можете попробовать удалить аннотацию @Repository - ведь класс GenericRepositoryImpl не является репозиторием, а скорее является базой для его реализации.

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

public interface UserRepository extends JpaRepository<User, Long> {
    void deleteByUserId(Long id);
}

, и если поле userId в вашем классе User аннотировано как идентификатор объекта, вам даже не нужен пользовательский метод, так как JpaRepository расширяет CrudRepository, которыйуже есть метод deleteById (идентификатор ID).

...