Hibernate 5.0.11を使用するSpring Boot 1.4.1を使用しています。最初に、次のようにapplication.properties
を使用してデータソースを構成しました。
spring.datasource.uncle.url=jdbc:jtds:sqlserver://hostname:port/db
spring.datasource.uncle.username=user
spring.datasource.uncle.password=password
spring.datasource.uncle.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.datasource.uncle.driverClassName=net.sourceforge.jtds.jdbc.Driver
「uncle」で構成しました。これは、構成する複数のデータソースの1つの名前になるためです。 Springのドキュメントに従って、私はこのデータソースを次のように構成しました:
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.uncle")
public DataSource uncleDataSource() {
return DataSourceBuilder.create().build();
}
この時点ですべてがうまくいきました。
@Entity
アノテーションなしで@Column
クラスを作成し、Hibernateに列名を認識させます。たとえば、idBank
という名前のJavaプロパティがある場合、Hibernateは自動的に列名はid_bank
です。これは、ddlを生成したり、SQLステートメントを実行したりするときに使用されます。多くのエンティティークラスを作成するので、この機能を利用したいと思います。 @Columnアノテーションをすべて維持します。この時点で、これは問題なく機能しました。
次に、次のような別のデータソースを追加しました。
spring.datasource.aunt.url=jdbc:sybase:Tds:Host2:port/db2
spring.datasource.aunt.username=user2
spring.datasource.aunt.password=password2
spring.datasource.aunt.dialect=org.hibernate.dialect.SybaseDialect
spring.datasource.aunt.driverClassName=com.sybase.jdbc4.jdbc.SybDriver
...そしてまた、これは、複数のデータソースを設定するためのSpringドキュメントに従っています。どうやら2番目のデータソースを定義すると、デフォルトのBeanを構成できなくなり、独自のEntityManager
とTransactionManager
を定義する必要があるようです。上記で構成したデータソースに加えて、次の構成を追加しました。
@Bean
@Primary
PlatformTransactionManager uncleTransactionManager(@Qualifier("uncleEntityManagerFactory") final EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
@Bean
@Primary
LocalContainerEntityManagerFactoryBean uncleEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(uncleDataSource())
.packages(Uncle.class)
.persistenceUnit("uncle")
.build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.aunt")
public DataSource auntDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
PlatformTransactionManager auntTransactionManager(@Qualifier("auntEntityManagerFactory") final EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
@Bean
LocalContainerEntityManagerFactoryBean auntEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(auntDataSource())
.packages(Aunt.class)
.persistenceUnit("aunt")
.build();
}
これは、データベースに接続してデータをフェッチしようとするという意味で機能します。
[〜#〜]ただし、[〜#〜](これが問題です。ここまで読んでくれてありがとう)これらの構成の後、Java列名を蛇のケース名に変換する暗黙の命名戦略を失ったため、JavaプロパティidBank
があると、誤って使用されますid_bank
の代わりに列名idBank
を使用します。この機能を元に戻したいのですが。
このspring.jpa.hibernate.naming-strategy
にはJPAプロパティがあり、SpringおよびHibernateにはorg.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
などのさまざまな命名戦略クラスがあります。だから私はこのように設定してみました:
spring.jpa.hibernate.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
しかし、それはうまくいきませんでした。私はいくつかのバリエーションを試しました:
spring.datasource.uncle.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
そして
spring.datasource.uncle.hibernate.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
しかし、これは効果がありませんでした。
次に、Hibernate 5で名前付け戦略が「物理的」と「暗黙的」の2つの部分に分けられ、それぞれに異なる設定があることを読みました。だから私はこれを試しました、いくつかのバリエーションがあります:
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
そして
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
そして
spring.datasource.uncle.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
そして
spring.datasource.uncle..hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
しかし、どれもうまくいきませんでした。
SessionFactory
など、この設定を直接Beanに設定する方法があるはずですが、そのAPIが見つかりませんでした。この周りのドキュメントにはいくつかのギャップがあるようです。
persistence.xml
も設定しないでください。これまでは必要ありませんでした。
だから私はここで行き詰まっているので、誰かが助けてくれることを願っています。これらのプロパティ設定をデバッグする方法が本当に欲しいのですが、org.springframework
とorg.hibernate
の両方でトレースログをオンにしましたが、何も役に立たなかったのです。これらのBeanが構成されているときにコードをステップ実行しようとしましたが、これが発生する場所が見つかりませんでした。もし誰かがその情報を持っていて、それを共有できたら、私は本当に感謝します。
私は同じ問題を抱えており、次のコードで修正しました(問題のコードに適応-単一のエンティティマネージャー用):
protected Map<String, Object> jpaProperties() {
Map<String, Object> props = new HashMap<>();
props.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
props.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
return props;
}
@Primary
@Bean(name = "defaultEntityManager")
public LocalContainerEntityManagerFactoryBean defaultEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(auntDataSource())
.packages(Aunt.class)
.persistenceUnit("aunt")
.properties(jpaProperties())
.build();
}
プロパティを使用して、@ ewertと同じ答えを得ることができます。
# this works
spring.jpa.properties.hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.properties.hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
# but that doesn't work
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
SessionFactoryを使用している場合は、次の行を使用して命名戦略を設定する必要があります。
sessionFactory.setImplicitNamingStrategy(SpringImplicitNamingStrategy.INSTANCE);
sessionFactory.setPhysicalNamingStrategy(new SpringPhysicalNamingStrategy());
Spring-Boot 2+でこれを正しく実行する唯一の方法は、手動で以下を設定することでした。
@Bean(name = "myEmf")
public LocalContainerEntityManagerFactoryBean sapEntityManagerFactory(
EntityManagerFactoryBuilder builder, @Qualifier("myDataSource") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("my.custom.package")
.persistenceUnit("myPu")
.properties(getProperties())
.build();
}
public Map<String, String> getProperties() {
val props = new HashMap<String, String>();
if (isTest()) {
props.put("hibernate.hbm2ddl.auto", "create");
} else {
props.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL95Dialect");
}
return props;
}