问题
I am using java.time.LocalDate of Java 8, and want to convert that to sql date so that it can be persisted. Here is my converter:
@Converter(autoApply = true)
public class LocalDatePersistenceConverter implements
AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate attribute) {
return java.sql.Date.valueOf(attribute);
}
@Override
public LocalDate convertToEntityAttribute(Date dbData) {
return dbData.toLocalDate();
}
}
Here is how it is getting used:
@Entity
@Access(AccessType.FIELD)
public class MutualFund implements Serializable {
@Id
private final String schemeName;
@Convert(attributeName="key",converter=LocalDatePersistenceConverter.class)
@ElementCollection
private Map<LocalDate, Price> nav;
//Other fields and methods
}
When I try to persist a MutualFund object, I get following exception:
java.lang.IllegalStateException: @Convert placed on Map attribute [mypackage.MutualFund.nav] must define attributeName of 'key' or 'value'
What is wrong in this code? Please help. Thanks.
回答1:
Your mapping of the Map is not completed so you are getting the exception.
There are two options for Map mapping, not sure which one you were trying to achieve.
A) The LocalDate key of the nav map is a field of the Price object:
@Embeddable
public class Price implements Serializable {
@Convert(converter=LocalDatePersistenceConverter.class)
//you don't need @convert if it is annotated with @Converter(autoApply = true)
public LocalDate mark;
public double price;
}
Then in your collection mapping you need to specify the key field used:
@ElementCollection
@MapKey(name="mark")
public Map<LocalDate, Price> nav;
B) The key element of nav is not part of the Price object, then you need to explicity map it to a column:
@Embeddable
public class Price implements Serializable {
public double price;
}
and the map annotation:
@Convert(converter=LocalDatePersistenceConverter.class)
@ElementCollection
@MapKeyColumn(name="mark")
public Map<LocalDate, Price> nav;
EDIT It turned out that Hibernate is most demanding than EclipseLink
With @Converter(autoApply = true) it works without pointing to the converter with both explicit and implicit key column.
@ElementCollection
@MapKeyColumn(name="mark") //this annotation can be omitted then the key column is called nav_KEY
public Map<LocalDate, Price> nav;
I could not make it work without autoApply. Persistence context could be build only if converter was declared with attributeName="key.":
@Convert(attributeName="key.", converter=LocalDatePersistenceConverter.class)
@ElementCollection
public Map<LocalDate, Price> nav = new HashMap<>();
but the converter was not correctly apllied. During schema generation the key column was tried to be generated as BLOB (and failed as no length was given) and serializaton instead of conversion was triggered during insert/fetching. I could not find a way to fix it.
来源:https://stackoverflow.com/questions/29861951/way-to-use-convert-to-convert-key-of-a-map-jpa