我有一个spring批处理应用程序(https://spring.io/projects/spring-batch)从.csv文件中读取逗号分隔的数据,然后将每个列Map到特定的java类bean,然后将其保存到数据库(postgres)。我的问题是,其中一个日期/时间列(称为end \dt)正在使用日期/时间的不正确时间部分写入数据库。您可以看到日期部分被正确读取(2023-04-15),但时间只是写为00:00:00.000000
更深入一点的步骤是:
spring批处理应用程序读入有多列的.csv文件,这个问题的关键是end\u dt,
在\u 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;
}
然后它接受这个解析日期/时间字符串并将其保存到我们将调用damasterrecord的数据类/javabean中,保存excel(.csv)文件中的所有列值
然后使用dozer,将数据类damasterrecord中的这些值Map到使用hibernate/jpa的实体类,该实体类将字符串date/time转换为java.sql.timestamp数据类型,即。
@Entity
@Table(name = "blah_blah_blah", schema = "some_schema", catalog = "some_catalog")
// code inbetween
public class MyRandomClassEntity {
private Timestamp endDt;
// more stuff
}
我知道damasterrecord数据类中的日期/时间字符串解析正确,因为我可以在调试器中看到它。就在dozer框架中调用mapper接口方法“mapper”之后,我通过调试器在entity类中看到错误的日期/时间。所以我不太确定dozer是如何进行Map的,但我猜dozer何时将字符串“dd-mmm-yyyy hh:mm:ss”Map到java.sql.timestamp数据类型,因为某些原因,它没有正确Map日期/时间字符串的“time”部分(它只做00:00:00.000000)。有人知道怎么解决这个问题吗?有很多接口和重写的方法,所以我还没有确定这种Map发生在哪里。
1条答案
按热度按时间disho6za1#
我能够解决这个问题,并将张贴我的答案在这里。我还想声明这是一个遗留应用程序(实际上并不太旧),但它使用了“timestamp”和“simpledateformat”(java8api之前的更新)等类,因此我的目的是以最小的努力解决这个问题/bug/问题,而不必重新编写应用程序。希望这对有类似应用程序/业务问题的任何其他开发人员都有用。
所以我第一次尝试延长推土机的速度
DozerConverter<String, LocalDateTime>
类为这个字符串->localdatetime对象创建我自己的自定义转换器。但是,在尝试Map数据库列使用的localdatetime对象->java.sql.timestamp数据类型时,我遇到了dozer抛出异常的问题。我们还有一个包含所有数据库配置的repo,所以我也不想进入这个依赖关系并编辑代码(这可能会破坏更多依赖它的组件),所以我暂时放弃了这个想法。当您使用这样的自定义转换文件时,dozer有一个.xml(在您的资源目录中)文件,您必须将此转换器附加到要Map的特定字段,例如:
我还尝试将datetime字符串的格式保留为“yyyy-mm-dd hh:mm:ss”,这是时间戳的格式。但是,每次它Map到我的数据库/实体类时,它总是出于某种原因将时间部分“剪切”到00:00:00.000000。
最后一个解决方案是第1个方案的一个变体,我创建了一个自定义转换器,但这次将它转换为
java.sql.Timestamp
数据类型。我试图避免使用这些旧的遗留类,但代码的其他部分似乎与之紧密耦合,我不想破坏一切。不管怎样,它成功了,我终于可以看到db将时间戳保存为完整的日期和时间。如果其他人有类似的问题,希望这能帮助他们。推土机有点奇怪,但你可以在这里了解更多:https://www.baeldung.com/dozer