2

Hibernate と Spring Data JPA を統合するための新しいメカニズムを理解しようとしました。https://www.baeldung.com/hibernate-5-springで提供されている例に従いましたが、役に立ちませんでした。さらなる調査により、Juergen HoellerによるGithub に関する次のような問題が発生しました。

[...] これは多くの出発点をカバーしています。Hibernate 5.2 および 5.3 では、LocalSessionFactoryBean および HibernateTransactionManager は、多くのシナリオで LocalContainerEntityManagerFactoryBean および JpaTransactionManager の 99% 互換性のある代替品として機能し、SessionFactory.getCurrentSession() との対話を可能にします (同じローカル トランザクション内の @PersistenceContext EntityManager インタラクションの横にある HibernateTemplate も) (#21454)。それはさておき、このようなセットアップは、JPA ブートストラップ コントラクトによって制約されることなく、より強力な Hibernate 統合 (#21494、#20852) とより多くの構成の柔軟性も提供します。

LocalSessionFactoryBeanクラスの対応する Javadoc には、次のように記載されています。

Spring 5.1 の時点で、Hibernate 5.0/5.1 および 5.2/5.3 と互換性があります。Hibernate 5.3 でセットアップされた LocalSessionFactoryBean は、一般的な JPA の目的で LocalContainerEntityManagerFactoryBean の即時の代替手段となります。特に Hibernate 5.3 では、Hibernate SessionFactory は JPA EntityManagerFactory インターフェースもネイティブに公開し、Hibernate BeanContainer 統合はすぐに登録されます。HibernateTransactionManager と組み合わせると、同じトランザクション内で JPA アクセス コードとネイティブ Hibernate アクセス コードを混在させることが自然に可能になります。

Spring Boot 2.1.2.RELEASE で簡単なサンプル プロジェクトを実装しました。シンプルな構成 (上記の Baeldung の例と同じ) を提供し、PostgreSQL データベースに接続します。さらに、理論的には、データを操作するためにモデルとリポジトリを使用します。クラスは次のようになります。

デモアプリケーション.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication
{

    public static void main(String[] args)
    {
        SpringApplication.run(DemoApplication.class, args);
    }
}

BasicConfig.java

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.config.BootstrapMode;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import org.postgresql.Driver;
import java.util.Properties;

@Configuration
@EnableJpaRepositories
public class BasicConfig
{
    @Bean
    public LocalSessionFactoryBean sessionFactory()
    {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan("com.example.demo");
        sessionFactory.setHibernateProperties(hibernateProperties());

        return sessionFactory;
    }

    @Bean
    public DataSource dataSource()
    {
        SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriverClass(Driver.class);
        dataSource.setUrl("jdbc:postgresql://localhost:5432/backend");
        dataSource.setUsername("backend");
        dataSource.setPassword("backend");

        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", "create-drop");
        hibernateProperties.setProperty(
                "hibernate.dialect", "org.hibernate.dialect.PostgreSQL95Dialect");

        return hibernateProperties;
    }
}

モデル.java

package com.example.demo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "model")
public class Model
{
    @Id
    @GeneratedValue
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    @Column(name = "name")
    private String name;
}

DemoRepository.java

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DemoRepository extends JpaRepository<Model, Long>
{
}

次の理由により、アプリを追加するとすぐにDemoRepositoryアプリが起動しなくなります。

A component required a bean named 'entityManagerFactory' that could not be found.


Action:

Consider defining a bean named 'entityManagerFactory' in your configuration.

完全なエラー メッセージ:

Exception encountered during context initialization - cancelling refresh
attempt: org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'demoRepository': 
Cannot create inner bean '(inner bean)#6c5ca0b6' of type  [org.springframework.orm.jpa.SharedEntityManagerCreator]  
while setting bean property 'entityManager';  
nested exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name '(inner bean)#6c5ca0b6': 
Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No bean named 'entityManagerFactory' available

SessionFactoryが適切に実装および公開されているという印象を受けましたEntityManagerFactoryが、そうではないようです。私の実装に欠陥があり、Baeldung の例が実際に正しく動作することは確かです。誰かが私にそれを指摘して、私の間違いを理解するのを手伝ってくれることを願っています.
事前にみんなに感謝します。

依存関係:

  • spring-data-jpa:2.1.4.RELEASE
  • spring-core:5.1.4.RELEASE
  • spring-orm:5.1.4.RELEASE
  • hibernate-core:5.3.7.Final
  • spring-boot:2.1.2.RELEASE

gradle.build

buildscript {
    ext {
        springBootVersion = '2.1.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.postgresql:postgresql'
}
4

1 に答える 1