我有一个Spring Framework 5.3.7应用程序,而不是Spring Boot (稍后我将转到Spring Boot )。我正在使用Java配置,到目前为止,它工作得很好。我有一个多maven模块项目,第一个模块是"myapp-entity“。有一个配置目录,其中包含以下文件:
@Configuration
@PropertySource(value = "file:/opt/myapp/myapp-ws.properties")
@EnableTransactionManagement
public class AppEntityConfiguration
{
@Value("${hibernate.connection.driver.class}")
private String driverClassName;
@Value("${hibernate.connection.url}")
private String connectionUrl;
@Value("${hibernate.connection.username}")
private String username;
@Value("${hibernate.connection.password}")
private String password;
@Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.app.model");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource dataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(connectionUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
public PlatformTransactionManager hibernateTransactionManager()
{
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
private final Properties hibernateProperties()
{
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "none");
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
return hibernateProperties;
}
}myapp-entity.jar可以用Java11编译得很好,这样就可以了。下一个maven模块是myapp-dao,它有一个config目录和一个配置类。
@Configuration
@Import(AppEntityConfiguration.class)
@ComponentScan(basePackages = "com.app.dao")
public class RepositoryContextConfiguration {
}我在app-entity.jar中定义了一个带有@Entity注释的TableOneEntity,这样就可以了。
我有一个用非常基本的函数列表定义的TableOneDao和TableOneDaoImpl。
public interface TableOneDao
{ ... list of functions }
@Repositories("tableOneDao")
public class TableOneDaoImpl implements TableOneDao
{ ... iplementation of functions }这方面的测试效果很好:
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@PropertySource(value = "file:/opt/myapp/myapp-ws.properties")
@ContextConfiguration(classes = RepositoryContextConfiguration.class)
public class OrganizationDaoTest extends BaseDaoTests
{
@Autowired
private TableOneDao tableOneDao;
}这在很大程度上是我以前做事情的方式,而且效果很好。现在,我想摆脱这种旧的做事方式,用一种新的方式做事。也许我不能在同一个项目中做到这一点,这可能是问题所在。
我有第二个实体(TableTwoEntity)和第二个存储库(TableTwoDao):
@Repository("clothesDryerDao")
public interface ClothesDryerDao extends JpaRepository<ClothesDryer, Long>
{
}这现在是一个JPA存储库,当我在这个Dao上执行简单操作时,它找不到这个Dao。
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@PropertySource(value = "file:/opt/ekotrope/ekotrope-ws.properties")
@ContextConfiguration(classes = RepositoryContextConfiguration.class)
public class ClothesDryerDaoTest extends TestCase
{
@Autowired
private ClothesDryerDao clothesDryerDao;
}我得到的错误如下:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.ekotrope.dao.ClothesDryerDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)
... 30 more我想我只需要修改RepositoryContextConfiguration如下:
@Configuration
@Import(EkotropeEntityConfiguration.class)
@ComponentScan(basePackages = "com.ekotrope.dao")
@EnableJpaRepositories(basePackages = "com.ekotrope.dao")
public class RepositoryContextConfiguration
{
}但这并不管用。事实上,我认为它破坏了其他工作测试。所以问题是..。我可以同时使用这两种方法(Dao和DaoImpl)和(JPA Dao)吗?或者,我应该只使用一个,如果是这样的话,我会使用JPA存储库。我只是想能够向不熟悉Spring的同事演示这两种方法。
因此,如果我能让这两个模块同时工作,那就太好了,但如果不能,我就可以再创建一个Maven模块,然后我就会有一个myapp-dao-old.jar和myapp-dao-new.jar。
谢谢你的帮助!
发布于 2021-05-28 05:10:27
我认为你的jpaRepositories配置是错误的,但你的道是好的。我认为这两个解决方案可以协同工作。
首先,您不需要在ClothesDryerDao接口上放置@Repository。(我知道您想使用限定符,但我不认为这是可行的,没有必要。(如果没有同一个类的多个实例,那么Type对于spring注入就足够了)
其次,我认为您需要更改您的Jpa配置。在一个项目中,我做过这样的事情
@Configuration
@EnableJpaRepositories(
basePackageClasses = ClothesDryerDao.class,
entityManagerFactoryRef = "configEntityManager",
)
public class RepositoryContextConfiguration{ /
//be careful this bean can maybe be in conflict with your sessionFactory
@Bean
public LocalContainerEntityManagerFactoryBean configEntityManager(DataSource dataSource) {
log.info("Start Parametrage Arcole Entity Manager");
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.app.model");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
return em;
}
}第三,我认为(这只是我的观点)你也许不应该在同一个包中混合经典的Dao和Repository。为了获得更好的可见性:)即使用法相同
https://stackoverflow.com/questions/67727893
复制相似问题