私のコードでこのエラーが発生しています。
org.springframework.beans.factory.BeanCreationException: 'roleRepository'という名前のBeanの作成エラー:Beanプロパティ 'entityManagerを設定しているときに、タイプ[org.springframework.orm.jpa.SharedEntityManagerCreator]の内部Bean'(内部Bean)#7540dc57 'を作成できません';ネストされた例外はorg.springframework.beans.factory.BeanCreationException:名前が「(インナーBean)#7540dc57」のBeanの作成中にエラーが発生しました:コンストラクター引数の設定中にBean 'entityManagerFactory'への参照を解決できません。ネストされた例外はorg.springframework.beans.factory.NoSuchBeanDefinitionException: 'entityManagerFactory'という名前のBeanがありません
私はこれらを見ました:
コンストラクタ引数の設定中はBean 'entityManagerFactory'への参照を解決できません
NoSuchBeanDefinitionException: 'entityManagerFactory'という名前のBeanはありません
NoSuchBeanDefinitionException: 'entityManagerFactory'という名前のBeanが定義されていません
それらのどれも私の質問に答えません。問題は解決できたのですが、質問があります。
関連するコードを共有してから、質問をします。
@Configuration
@EnableTransactionManagement
public class HibernateConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerF() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] {"com.gitreporter"});
JpaVendorAdapter jpaAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(jpaAdapter);
em.setJpaProperties(jpaProperties());
return em;
}
@Bean
public PlatformTransactionManager jpaTransactionManager(EntityManagerFactory emf) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(emf);
return jpaTransactionManager;
}
private final Properties jpaProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return properties;
}
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/MyDBNAME?useSSL=false");
dataSource.setUsername("username");
dataSource.setPassword("password");
return dataSource;
}
問題はこの行にありました:
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerF() {
次のように、medhod名をentityManagerFactoryに変更しました。
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
明示的に指定されない限り、デフォルトでBeanの名前はメソッド名と同じになるため、コンテキスト内のファクトリBeanの名前を「entityManagerFactory」と等しくします。
私の質問:JPA APIには、Springコンテナー内で「慣例として」「entityManagerFactory」という名前のEntityManagerFactory Beanを探している場所はありますか?メソッドの名前が「entityManagerF」の場合、なぜ機能しないのですか?
残りのコードは次のとおりです。
@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
public List<T> findByAttributeContainsText(String attributeName, String text);
}
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements GenericRepository<T, ID> {
private EntityManager entityManager;
public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
}
public interface RoleRepository extends GenericRepository<Role, Long> {
}
答えを見つけました。
@EnableJpaRepositoriesアノテーションの documentation をチェックアウトします。
オプションの要素では、次のようになります。
entityManagerFactoryRefこのアノテーションで検出されたリポジトリを作成するために使用されるEntityManagerFactory Bean定義の名前を構成します。
ページに移動して詳細を確認すると、次のように表示されます。
entityManagerFactoryRef
パブリック抽象文字列entityManagerFactoryRef
EntityManagerFactory Bean定義の名前を このアノテーションで発見されたリポジトリを作成するために使用されます。デフォルトはentityManagerFactoryです。
戻り値:
デフォルト: "entityManagerFactory"
したがって、この「従来の」デフォルト構成は、@ EnableJpaRepositoriesアノテーション自体からのものです。
はい、そう思います。あなたの場合、SpringはBean entityManagerFactory
を事前に設定しています。
@EnableAutoConfiguration
のjavadocからの抜粋
Enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need. Auto-configuration classes are usually applied based on your classpath and what beans you have defined. For example, if you have Tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory (unless you have defined your own ServletWebServerFactory bean).
そして、休止状態の構成を見て、
private final Properties jpaProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return properties;
...だと思います。これは呼び出される必要があります。これはJpaBaseConfiguration
から派生しています
@Configuration
@ConditionalOnSingleCandidate(DataSource.class)
class HibernateJpaConfiguration extends JpaBaseConfiguration {
また、JpaBaseConfiguration
には、オーバーライドしようとしているentityManagerFactory
のBean定義がありました。
@Bean
@Primary
@ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class,
EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder factoryBuilder) {
Map<String, Object> vendorProperties = getVendorProperties();
customizeVendorProperties(vendorProperties);
return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan())
.properties(vendorProperties).mappingResources(getMappingResources())
.jta(isJta()).build();
}
編集:-OPの回答に感謝します。したがって、次のような宣言を通じてカスタムBean名を提供するために使用することもできます
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerF",
)
https://stackoverflow.com/a/45665826/5107365 にある別のstackoverflowスレッドは、この問題についてより深い洞察を提供します。