簡體   English   中英

using “Dozer” in Java to map String of date/time to java.sql.Timestamp and save in DB is writing time as 00:00:00.000000

[英]using “Dozer” in Java to map String of date/time to java.sql.Timestamp and save in DB is writing time as 00:00:00.000000

I have a Spring Batch application ( https://spring.io/projects/spring-batch ) that reads comma delimited data from a.csv file and then maps each column to specific Java class beans, the saves it to a database (postgres )。 我的問題是,名為END_DT的日期/時間列之一正在使用日期/時間的不正確時間部分寫入數據庫。 您可以看到日期部分已正確讀取(2023-04-15),但時間僅寫為 00:00:00.000000

在此處輸入圖像描述

它執行更深入的步驟是:

  1. Spring 批處理應用程序讀入.CSV 文件,它有多個列,這個問題的重要一個是end_dt
  2. end_dt列中,使用以下方法解析出格式為dd-mmm-YYYY HH:mm:ss (即 29-Apr-2099 23:59:59)的字符串:
private String getDateTimeString(String dateString) {

        SimpleDateFormat sdfTo = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
        SimpleDateFormat sdfFrom = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
        String formattedDateTimeStr = null;
       
            if (StringUtils.isNotEmpty(dateString)) {
                formattedDateTimeStr = sdfTo.format(sdfFrom.parse(dateString));
          }
        
        return formattedDateTimeStr;
}
  1. 然后它將這個解析日期/時間字符串保存到我們將調用DaMasterRecord的數據類/Java Bean 中,保存 excel (.csv) 文件中的所有列值
  2. Then using Dozer , these values from the data class DaMasterRecord are mapped to an Entity class that uses Hibernate/JPA which makes the String date/time to a java.sql.Timestamp data type, ie
@Entity
@Table(name = "blah_blah_blah", schema = "some_schema", catalog = "some_catalog")
// code inbetween

public class MyRandomClassEntity {
  private Timestamp endDt;

// more stuff
}

我知道在 DaMasterRecord 數據 class 中正確解析了日期/時間字符串,因為我可以在調試器中看到它。 就在 Dozer 框架中調用 Mapper 接口方法“mapper”之后,我通過調試器看到實體 class 中列出的錯誤日期/時間。 So I'm not exactly sure how Dozer is doing it's mappings, but I'm guessing when Dozer goes to map the String that is "dd-mmm-YYYY HH:mm:ss" to a java.sql.Timestamp datatype, for某些原因它不能正確地 map 日期/時間字符串的“時間”部分(它只是 00:00:00.000000)。 有誰知道如何解決這一問題? 有很多接口和覆蓋的方法,所以我還沒有完全確定這個映射發生在哪里。

我能夠解決這個問題,並將在這里發布我的答案。 我還想 state 這是一個遺留應用程序(實際上不是太舊),但它使用諸如“時間戳”和“SimpleDateFormat”之類的類(Java 8 之前的 API 更新),所以我的目的是解決這個問題/錯誤/問題用最少的努力,不必重新編寫應用程序。 希望這對有類似應用程序/業務問題的任何其他開發人員有用。

  1. 所以我首先嘗試擴展 Dozer 的DozerConverter<String, LocalDateTime> class 來為這個 String -> LocalDateTime object 創建我自己的自定義轉換器。 However, I ran into issues with Dozer throwing exceptions trying to map the LocalDateTime object -> java.sql.Timestamp data type that our database column uses. 我們有另一個包含所有數據庫配置的存儲庫,所以我不想將 go 放入該依賴項並編輯代碼(這可能會破壞更多依賴它的組件),所以我暫時放棄了這個想法.

當您使用這樣的自定義轉換時,Dozer 有一個.xml(在您的資源目錄中)文件,您必須將此轉換器附加到您嘗試 map 的特定字段,例如:

<field custom-converter="com.mydomainname.my.namespace.MyCustomConverter">
     <a>theColumnNameIamMappingFrom</a>
     <b>theColumnNameIamMappingTo</b>
</field>
  1. 我還嘗試將 DateTime 字符串的格式保持為“yyyy-MM-dd HH:mm:ss”,這是時間戳的格式。 但是,每次它映射到我的數據庫/實體 class 時,它總是出於某種原因將時間部分“削減”到 00:00:00.000000。

  2. 所以最后一個解決方案是第一個的變體,我創建了一個自定義轉換器,但這次讓它轉換為java.sql.Timestamp數據類型。 我試圖避免使用這些舊的遺留類,但代碼的其他部分似乎與它過於緊密耦合,我不想破壞一切。 無論如何,它起作用了,我終於能夠看到數據庫將時間戳保存為完整的日期和時間,即

2020-08-31 23:59:59.123456

希望這可以幫助其他人,如果他們有類似的問題。 推土機有點奇怪,但你可以在這里閱讀更多信息: https://www.baeldung.com/dozer

暫無
暫無

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

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