JPA规范只提供了两种应用转换器的选项:全局@Converter(autoApply = true)
和字段级别@ Convert(converter = FooConverter.class)
(或它们的XML等效项)。
JPA转换器仅了解实体属性类型和数据库列类型。 没有访问实体实例甚至实体类型以构建条件(由实体字段)转换逻辑。
您可以像这样通过编程方式添加一个AttributeConverter
转换器:
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource)
builder.addAnnotatedClasses(FooBarEntity.class)
builder.addAttributeConverter(FooConverter.class, /*autoApply:*/true)
EntityManagerFactory entityManagerFactory = builder.buildSessionFactory()
我不确定有比使用@Convert(converter = FooConverter.class)
更简洁的方法来告诉Hibernate仅转换特定实体字段。
将转换器应用于特定实体字段的解决方法:
包装类
创建需要转换的字符串的包装器:
public class Bar {
private final String value;
public Bar(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
@Entity
public class FooBarEntity {
private Bar barField;
public void setBarField(String value) {
this.barField = new Bar(value);
}
}
声明一个自动应用的转换器:
@Converter(autoApply = true)
public class FooConverter implements AttributeConverter<Bar, String> {
@Override
public String convertToDatabaseColumn(Bar bar) {
return Optional.ofNullable(bar).map(Bar::getValue).orElse(null);
}
@Override
public Status convertToEntityAttribute(String value) {
return Optional.ofNullable(value).map(Bar::new).orElse(null);
}
}
JPA实体监听器
如果需要将String
类型转换为String
类型(即源类型和目标类型相同),则可以使用实体监听器。实体监听器可以访问实体本身,因此可以具备复杂的条件逻辑。
@Entity
public class FooBarEntity {
private String barField;
}
创建一个实体监听器:
public class FooEntityListener {
@PrePersist
@PreUpdate
public void convertToDatabaseColumn(Object entity) {
if (entity instanceof FooBar) {
entity.setBarField(entity.getBarField());
}
}
@PostLoad
public void convertToEntityAttribute(Object entity) {
if (entity instanceof FooBar) {
entity.setBarField(entity.getBarField());
}
}
}
在 META-INF/orm.xml 中注册默认实体监听器:
<entity-mappings>
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="com.example.FooEntityListener"/>
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
addAttributeConverter(org.hibernate.cfg.AttributeConverterDefinition)
,以便与https://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/cfg/AttributeConverterDefinition.html一起使用? - rakwaht