hibernate - SpringBoot JPA 2.1 Converter 忽略 convertToDatabaseColumn
问题描述
我有以下转换器
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter(autoApply = true)
public class ImportedReasonConverter implements AttributeConverter<ImportedReason, String> {
@Override
public String convertToDatabaseColumn(final ImportedReason pImportedReason) {
return pImportedReason.getValue();
}
@Override
public ImportedReason convertToEntityAttribute(final String pImportedReason) {
return ImportedReason.of(pImportedReason);
}
}
由实体使用,例如
@Entity
@Table(
name = "IMPORT_RECORD"
)
public class ImportRecordEntity implements Serializable {
private static final long serialVersionUID = 2483327758356663412L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private UUID id;
@Column(name = "importedReason")
private ImportedReason importedReason;
public ImportedReason getImportedReason() {
return importedReason;
}
public void setImportedReason(final ImportedReason importedReason) {
this.importedReason = importedReason;
}
{...}
}
在启动应用程序时,表由 Hibernate 创建,使用正确的列类型(这里:VARCHAR)。删除 autoApply=true 设置会导致启动失败 - 因此转换器本身会被识别。
但是:在保存带有设置为importedReason的值的实体时,我得到一个
Caused by: java.io.NotSerializableException: ImportedReason
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1185)
at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1553)
at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1510)
at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1433)
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:349)
at org.hibernate.internal.util.SerializationHelper.serialize(SerializationHelper.java:115)
... 43 more
尝试调试我的转换器,不会调用 ImportedReasonConverter.convertToDatabaseColumn(ImportedReason) 方法。因此,Hibernate 不会尝试写入 String 类型的值,而是输入 ImportedReason。
任何想法,为什么转换器不能正确使用?我已经使用 Java 8 + 11 和 Spring 2.1.5.RELEASE + 2.1.9.RELEASE (早期版本用于另一个项目)进行了尝试。我也尝试过使用其他一些转换器(例如内部类型 -> LocalDateTime),但我也有同样的问题。
非常感谢。斯特凡
解决方案
更新: 进一步调查显示,正在保存的实体已被全面分析,其转换器得到正确使用。 但是:如果该实体使用其他一些实体作为参考,而后者又使用要使用这些转换器转换的类型:那是它看到值但不使用转换器(出于某种原因)的时候。
因此,我在上面的 ImportRecordEntity 用于以下 PortfolioEntity,我实际上是在尝试保存它。保存 ImportRecordEntity 毫不费力。然后我将这个 ImportRecordEntity 实例(从保存方法返回)设置为 PortfolioEntity 实例并保存它。但是随后 Hibernate 崩溃了,因为它似乎分析了 PortfolioEntity 而不是 ImportRecordEntity ,它持有 ImportedReason - 所以它不知道 ImportedReasonConverter (参见 org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(Object, EntityKey, EntityPersister, boolean, Object, EventSource, boolean) - AbstractSaveEventListener.java:122 变量类型)。
@Entity
@Table(
name = "PORTFOLIO"
)
public class PortfolioEntity implements Serializable {
private static final long serialVersionUID = 3632725596750538287L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private UUID id;
@Column(name = "IMPORT_RECORD")
private ImportRecordEntity importRecord;
{...}
}
推荐阅读
- azure - 如何在 Azure Runbook 中多次执行自定义脚本执行?
- github - RStudio 和 Travis CI 构建检查不匹配 (libudunits2.so)
- ios - 在 ViewController 中检测 SKNode 的触摸
- tfs - 如果uninstall.exe存在运行卸载步骤否则跳转到安装vNext构建任务
- java - 如何在不干扰实际类的情况下模拟来自另一个类(测试类)的扫描仪输入
- python - 对模型的关系感到困惑
- javascript - IE7 中的 Javascript 函数
- osgi - 系统捆绑包如何访问系统包?
- r - 复杂的分组和计数
- c# - 带有 Restsharp 的 RestCall 未经过身份验证,它与 Postman 一起使用