我有一个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;
}
感觉找不到通用类型的域类。
答案 0 :(得分:0)
您的GenericRepository
接口和GenericRepositoryImpl
类适合custom repository implementations in Spring Data JPA中使用的存储库片段模式,因此我的猜测是Spring Data试图实例化它以供使用。我会尝试将GenericRepositoryImpl
重命名为AbstractGenericRepository
或使其成为抽象类,或者可能两者兼而有之。您还可以尝试删除@Repository
注释-毕竟所有类GenericRepositoryImpl
都不是存储库,而是实现它的基础。
编辑: 从您的代码看来,您似乎正在使用GenericRepository创建具有自定义方法的存储库,以按ID删除用户。话虽如此,我相信这段代码就足够了:
public interface UserRepository extends JpaRepository<User, Long> {
void deleteByUserId(Long id);
}
并且如果您的User类中的字段userId是注释为实体ID的字段,则您甚至不需要自定义方法,因为JpaRepository扩展了CrudRepository,该对象已经具有方法deleteById(ID id)。