JPA / Hibernate が発行する SQL のカラム名がスネークケースで困った時にすること
この記事について
Spring Boot 3 でデータベースアクセス用の Java アプリを作成していた際、JPA / Hibernate が発行する SQL のカラム名およびテーブル名がキャメルケース (camelCase) ではなく、スネークケース (snake_case) になってしまい、解決までに無駄な時間を溶かしてしまったので、備忘録として残しているものです。
結論
はじめに結論を書いておくと、application.properties
で以下の 1 行を追加していなかったのが原因です。
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
実際の Spring Boot アプリコード
コミュニティ内で使用する用に書いたチュートリアルコードがあるので、それを見てください。
どんな SQL が発行されていたのか
JPA / Hibernate で発行されていた SQL は、application.properties
で指定をしない限り、既定動作でカラム名やテーブル名を自動でスネークケース (snake_case) に変換します。
select
c1_0.customerid,
c1_0.company_name,
c1_0.email_address,
c1_0.first_name,
c1_0.last_name,
c1_0.middle_name,
c1_0.modified_date,
c1_0.name_style,
c1_0.password_hash,
c1_0.password_salt,
c1_0.phone,
c1_0.rowguid,
c1_0.sales_person,
c1_0.suffix,
c1_0.title
from
saleslt.customer c1_0
以下のように、Entity クラスでアノテーションを使用して CamelCase のカラム名やテーブル名を明示しても、application.propertiesで 1 行書き忘れると、裏で勝手に snake_case になるのは落とし穴でした。
@Data
@Entity
@Table(schema = "SalesLT", name = "Customer")
public class Customer {
@Id
@Column(name = "CustomerID", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int customerId;
@Column(name = "NameStyle", length = 1, nullable = false)
private String nameStyle;
@Column(name = "Title", length = 8)
private String title;
@Column(name = "FirstName", length = 100, nullable = false)
private String firstName;
@Column(name = "MiddleName", length = 100)
private String middleName;
@Column(name = "LastName", length = 100, nullable = false)
private String lastName;
@Column(name = "Suffix", length = 10)
private String suffix;
@Column(name = "CompanyName", length = 128)
private String companyName;
@Column(name = "SalesPerson", length = 256)
private String salesPerson;
@Column(name = "EmailAddress", length = 50)
private String emailAddress;
@Column(name = "Phone", length = 50)
private String phone;
@Column(name = "PasswordHash", length = 128, nullable = false)
private String passwordHash;
@Column(name = "PasswordSalt", length = 10, nullable = false)
private String passwordSalt;
@Column(name = "rowguid", nullable = false)
@GeneratedValue(strategy = GenerationType.UUID)
private String rowguid;
@Column(name = "ModifiedDate", nullable = false)
private Calendar modifiedDate;
}
ちなみに、この部分に気が付くまでに、私は 1 時間時間を溶かしてしまいました。
最終的に、以下の海外ニキの記事を見つけることができ、あっ、と気が付くことができたので、大変助かりました。
application.properties 修正後の SQL
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
を設定することで、きちんとアノテーションで明示した通りの SQL になりました。
なお、実際に自分の環境で確認したい方は、application.properties
に spring.jpa.show-sql=true
を設定することを忘れずに。
select
c1_0.CustomerID,
c1_0.CompanyName,
c1_0.EmailAddress,
c1_0.FirstName,
c1_0.LastName,
c1_0.MiddleName,
c1_0.ModifiedDate,
c1_0.NameStyle,
c1_0.PasswordHash,
c1_0.PasswordSalt,
c1_0.Phone,
c1_0.rowguid,
c1_0.SalesPerson,
c1_0.Suffix,
c1_0.title
from
SalesLT.Customer c1_0
Discussion