Calendar 和 mysql DATETIME 之间的 OpenJPA 和 AttributeConverter 不起作用

问题描述 投票:0回答:1

OpenJPA3.2.2 支持

AttributeConverter
但我总是遇到强制转换错误。
class java.lang.String cannot be cast to class java.util.Calendar (java.lang.String and java.util.Calendar are in module java.base of loader 'bootstrap')

我尝试了

String, java.sql.Timestamp, java.util.Date
“db type”,但 OpenJPA 给出了强制转换错误。我应该在属性转换器中为 Mysql DATETIME 使用什么类型?

由于遗留原因,Java bean 必须使用

Calendar

 字段,这是多个应用程序使用的旧代码库。如果不在字段中使用 
@Convert
 注释,则日历将保存到数据库中,但我需要将日历值强制为 utc 时区 
yyyy-MM-dd HH:mm:ss

@Entity @Table(name="service") @Access(AccessType.FIELD) public class Service { ... @Column(nullable=false) @Convert(converter=JPAConverter.class) private Calendar updated; } CREATE TABLE IF NOT EXISTS service ( id bigint UNSIGNED NOT NULL default '0', updated datetime NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB; @Converter(autoApply=false) public class JPAConverter implements AttributeConverter<Calendar, String> { @Override public String convertToDatabaseColumn(Calendar val) { if(val==null) return null; return DateUtil.formatDateTime(val, DateUtil.TIMEZONE_UTC); } @Override public Calendar convertToEntityAttribute(String dbVal) { if(dbVal==null) return null; return DateUtil.parseDateTimeFromUTC(dbVal); } }
Stackrace 是

Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.Calendar (java.lang.String and java.util.Calendar are in module java.base of loader 'bootstrap') at org.apache.openjpa.jdbc.sql.DBDictionary.setTyped(DBDictionary.java:1551) at org.apache.openjpa.jdbc.sql.RowImpl.flush(RowImpl.java:1002) at org.apache.openjpa.jdbc.sql.RowImpl.flush(RowImpl.java:962) at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:119) at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushAndUpdate(BatchingPreparedStatementManagerImpl.java:80) at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:102) at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:90) at org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:555) at org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:109) at org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:61) at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:109) at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:81) at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:755) at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:146) at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2310) at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2201) at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2118) ... 55 more
    
mysql jpa openjpa
1个回答
0
投票
我不得不放弃

AttributeConverter

并使用openjpa特定功能。也许使用 OpenJPA4.x 库效果更好,但我现在不想更改 
javax.* to jakarta.*
 包名称。

import org.apache.openjpa.persistence.Externalizer; import org.apache.openjpa.persistence.Factory; @Factory("JPAUtil.db2calendar") // utc-to-calendar @Externalizer("JPAUtil.calendar2db") @Column(nullable=false) @Temporal(TemporalType.TIMESTAMP) private Calendar created; public class JPAUtil { private static DateTimeFormatter calFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC); public static String calendar2db(Calendar val, StoreContext ctx) { if(val==null) return null; return calFormat.format(val.toInstant()); } public static Calendar db2calendar(String val, StoreContext ctx) { if(val==null) return null; Calendar cal = Calendar.getInstance(); cal.setTimeInMillis( Instant.from(calFormat.parse(val)).toEpochMilli() ); return cal; } }
    
© www.soinside.com 2019 - 2024. All rights reserved.