簡體   English   中英

春季啟動-JPA休眠-Mysql UTF8原因:com.mysql.jdbc.MysqlDataTruncation:數據截斷:數據對於列而言太長

[英]Spring boot - JPA Hibernate - Mysql UTF8 Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column

我的Windows計算機上的MySql 5.7 Spring Boot 1.4.0 RELEASE mysql jdbc驅動程序是5.1.39

我有一個表,有幾個VARCHAR列,它們都設置為VARCHAR(100)。 編碼設置為: ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 為表。

我已驗證,如果使用MYSql Workbench,則可以插入100個非英文字符(例如中文)。

現在到我的Java代碼中,我要插入的字段是一個西班牙字符串, getBytes().length返回115,因此為115字節。

由於DB中的字段為100個字符,因此我認為插入115個字節的字符串應該不會有問題。 但這是我的問題,我得到了:

Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'addr1' at row 1

我試圖將useUnicode=true&connectionCollation=utf8_general_ci&characterSetResults=utf-8&characterEncoding=utf-8到URL,嘗試將connectionProperty添加為useUnicode=true;characterEncoding=utf-8; 到我的application.yaml等,沒有運氣

然后我將@EnableAutoConfiguration更改為@Configuration並添加以下內容:

@Bean
public DataSource datasource() {
    org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
    ds.setDriverClassName(databaseDriverClassName);
    ds.setUrl(datasourceUrl);
    ds.setUsername(databaseUsername);
    ds.setPassword(databasePassword);
    ds.setConnectionProperties("useUnicode=true;characterEncoding=utf-8;");
    ds.setInitSQL("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';");

    return ds;

}

@Bean
public EntityManagerFactory entityManagerFactory() {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(false);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.xxx.xxx.entity");
    Properties properties = new Properties();
    properties.setProperty("hibernate.connection.useUnicode", "true");
    properties.setProperty("hibernate.connection.charSet", "utf8mb4");
    properties.setProperty("hibernate.connection.characterEncoding", "utf8mb4");
    properties.setProperty("hibernate.id.new_generator_mappings", "false");
    factory.setJpaProperties(properties);
    factory.setDataSource(datasource());
    factory.afterPropertiesSet();

    return factory.getObject();
}

還是一樣!

我現在花了兩天時間... :-(我想這肯定是我犯的一個簡單錯誤,但是錯誤是什么?

謝謝

編輯:嘗試只通過調用存儲庫接口保存記錄,它起作用了! 因此,問題在於調用了entitymanager.merge()。 我需要為實體管理器設置任何屬性以處理UTF8嗎?

編輯:我添加了更多的調試代碼,現在問題似乎與JPA或休眠無關...

我得到的字符串是從SOAP調用到magento SOAP API。 現在是我的代碼:

    String s = "其次受影響較大的是金融體系,過去那么多年金融體系受益於低利率、信貸寬松、影子銀行大擴張等,金融企業瘋狂的擴張資產負債表,一個個都賺的缽滿盆滿(看看過去數年金融企業的瘋狂高利潤和增速,從業人員增速和工";
    salesOrderModel.setAddr1(s);

    try {
        System.out.println(s + ", " + "[" + s.length() + "][" + s.getBytes("UTF-8").length + "]");
    } catch (Exception e) {
        e.printStackTrace();
    }

使用上面的代碼, entitymanager.merge()可以正常工作,並且將數據插入到數據庫中,這是系統輸出:

其次受影響較大的是金融體系,過去那么多年金融體系受益於低利率、信貸寬松、影子銀行大擴張等,金融企業瘋狂的擴張資產負債表,一個個都賺的缽滿盆滿(看看過去數年金融企業的瘋狂高利潤和增速,從業人員增速和工, [99][297]

現在,如果我注釋掉B1和B2,並取消注釋A1和A2:

salesOrderModel.setAddr1(address.getStreet());
    String s = address.getStreet();


    try {
        System.out.println(s + ", " + "[" + s.length() + "][" + s.getBytes("UTF-8").length + "]");
    } catch (Exception e) {
        e.printStackTrace();
    }

我收到了帖子開頭提到的異常,這是系統輸出:

Plaça Pla de L'Estany, 5, Edificio Vueling Airlines S.A., [113][115]

字符串長度為113。

如果我這樣做:

String s = "Plaça Pla de L'Estany, 5, Edificio Vueling Airlines S.A.";

輸出為:

Plaça Pla de L'Estany, 5, Edificio Vueling Airlines S.A., [56][57]

現在,字符串長度為56(vs 113)。 為什么?

終於我終於找到了問題,我的愚蠢錯誤!

對於該字段,字符串確實太長。 基本上,該字符串包含兩行Plaça Pla de L'Estany, 5, Edificio Vueling Airlines SA ,直到現在我都沒有注意到。

我的錯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM