mrmapleleaf
@mrmapleleaf (Kaede Maruyama)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

JDBCでhibernateを使ってデータベースに日本語を書き込むと文字化けする

解決したいこと

現在、JavaのJPAの使い方を勉強中です。
hibernateを使って、データベースに日本語でデータを書き込もうとした際、データベース内で文字化け(文字が全て"?"に置き換えられる)が発生してしまいました。
いろいろ調べてみましたが、persistence.xmlなどjdbc、hibernateの設定に不備があるのか、データベース側に問題があるのかわからなくなり、詰まってしまった為、アドバイスを頂きたく思います。

発生している問題・エラー

+----+-----------+-------+---------------------+
| id | title | price | created_at |
+----+-----------+-------+---------------------+
| 1 | onigiri | 300 | 2020-12-02 20:36:25 |
| 2 | ??? | 300 | 2020-12-02 21:56:31 |
| 3 | お辞儀 | 1000 | 2020-12-02 22:02:31 |
+----+-----------+-------+---------------------+

id=2が実際に下記のソースコードを実行した結果です。
英数で入力した場合は、id=1のようにちゃんと表示されました。
また、ターミナルから直接INSERT INTO person (title, price) VALUES ("お辞儀", 1000);を入力した際には、id=3の様に望む結果を得ることができました。

該当するソースコード

DTO

package entity;

import java.sql.Timestamp;

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

@Entity
@Table(name = "person")
public class Kadaidb {

    @Id
    @Column(name = "ID")
    private int id;

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

    @Column(name = "price")
    private int price;

    @Column(name = "created_at", nullable = false)
    private Timestamp created_at;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public Timestamp getCreated_at() {
        return created_at;
    }

    public void setCreated_at(Timestamp created_at) {
        this.created_at = created_at;
    }


}

DAO

package util;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class DBUtil {

    private static final String PERSINTENCE_UNIT_NAME = "kadaidb01";
    private static EntityManagerFactory emf;

    public static EntityManager createEntityManager() {
        return _getEntityManagerFactory().createEntityManager();
    }

    private static EntityManagerFactory _getEntityManagerFactory() {
        if(emf == null) {
            emf = Persistence.createEntityManagerFactory(PERSINTENCE_UNIT_NAME);
        }

        return emf;
    }
}

main

package action;

import java.sql.Timestamp;

import javax.persistence.EntityManager;

import entity.Kadaidb;
import util.DBUtil;

public class JpaTest01 {

    public static void main(String[] args) {
        // TODO 自動生成されたメソッド・スタブ

        EntityManager em = DBUtil.createEntityManager();

        Kadaidb kdb = new Kadaidb();
        kdb.setTitle("お辞儀");
        kdb.setPrice(300);
        Timestamp currentTime = new Timestamp(System.currentTimeMillis());
        kdb.setCreated_at(currentTime);

        em.getTransaction().begin();
        em.persist(kdb);
        em.getTransaction().commit();
        em.close();
    }

}

personテーブル詳細

+------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(100) | YES | | NULL | |
| price | int(11) | YES | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | |
+------------+--------------+------+-----+-------------------+----------------+

解決に必要な情報が不足していましたら、申し訳ありません。お声掛けいただければすぐに確認、追記したいと思います。
アドバイス等、お待ちしております。

追記

質問投稿して早々ですが、解決いたしました。備忘録として、追記しています。

persistence.xmlのjdbc接続プロパティーで、URLの部分を?useSSL=falseから?useUnicode=true&characterEncoding=utf8に変更した所、日本語でも追加される様になりました!

データベースに設定されている文字コードを$show variables like "chara%"で調べた所、character_set_serverlatin1になってしまっているのが影響してしまっているのかなと思いましたが、直接SQL文を使用した際には普通に登録できたのでモヤモヤしております...。以前は普通に日本語を登録できたのに、数日開けて使ったらこんなことになっていたのは何故なのか?

1

No Answers yet.

Your answer might help someone💌