java - HashMap 到 Spring JPA 的映射扩展
问题描述
我决定创建以下对象:
public class ScoreMap<T> extends HashMap<T, Double>
我想将它们保存在数据库中:
@ElementCollection(fetch = FetchType.EAGER)
private Map<String, Double> keywords = new ScoreMap<>();
效果很好。一切都按预期保存。
现在,在检索时,我似乎无法在没有 TypeCasting 的情况下返回 ScoreMap:
public ScoreMap<String> getKeywords()
{
return (ScoreMap<String>)keywords;
}
这样做我得到以下错误:
Servlet.service() for servlet [dispatcherServlet] in context with path [/myApp] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: org.hibernate.collection.internal.PersistentMap cannot be cast to entity.ScoreMap (through reference chain: java.util.ArrayList[0]->entity.Document["document_knowledge"]->entity.DocumentKnowledge_$$_jvst505_2["keywords"])] with root cause
java.lang.ClassCastException: org.hibernate.collection.internal.PersistentMap cannot be cast to entity.ScoreMap
我尝试将ScoreMap更改为:
public class ScoreMap<T> extends HashMap<T, Double> implements Map<T, Double>
结果相同。
我需要返回一个ScoreMap以在那里使用其他方法。
我知道我可以轻松地foreach并重新创建对象,但我希望我可以避免这种情况。
那么对于这种情况,哪种方法最好呢?我只是设计了这个明显错误的东西还是我错过了其他东西?
解决方案
我建议你另一种方法。代表团。
你为什么不直接实现接口并接受另一个实例作为构造函数参数,而不是扩展? HashMap<K, V>
Map<K, V>
Map
class ScoreMap<T> implements Map<T, Double> {
private final Map<T, Double> delegate;
ScoreMap(final Map<T, Double> delegate) {
this.delegate = delegate;
}
...
@Override
public Double get(final Object key) {
// Apply custom logic, if needed
return delegate.get(key);
}
// And so on...
}
然后,使用 agetter
和 asetter
@Entity
@...
class YourEntity {
...
private Map<String, Double> keywords;
@ElementCollection(fetch = FetchType.EAGER)
public ScoreMap<String> getKeywords() {
// This is fine as we know the Map will always be a ScoreMap
return (ScoreMap<String>) keywords;
}
public void setKeywords(final Map<String, Double> keywords) {
this.keywords = new ScoreMap<>(keywords);
}
}
正如您所看到的,每次 Hibernate设置时Map
,您都会将其包装在您的ScoreMap
中,并具有额外的自定义逻辑。
为了您的兴趣,HibernatePersistentMap
确实实现了该Map
接口,因此您的ScoreMap
.
休眠文档状态
作为要求,必须将持久集合值字段声明为接口类型(参见示例 7.2,“使用 @OneToMany 和 @JoinColumn 的集合映射”)。实际的接口可能是 java.util.Set、java.util.Collection、java.util.List、java.util.Map、java.util.SortedSet、java.util.SortedMap 或任何你喜欢的东西(“任何你喜欢的东西”意味着您必须编写 org.hibernate.usertype.UserCollectionType 的实现)。
所以我将编辑我上面的例子。
作为最后的手段,你可以看看UserCollectionType
推荐阅读
- c# - 如何在 .NET Core 3 启动期间获取控制器信息
- mongoose - 如果虚拟填充字段长度大于 0,则返回 mongoose 文档
- c# - 在子对话框上调用 EndDialogAsync 时,不会在父对话框上调用 ResumeDialogAsync
- java - JaxB 解组带有重复标签的奇怪 XML
- excel - 自动将文本框中的数据从一个使用表单粘贴到另一个使用空文本框的使用表单
- azure-devops - 如何在任务自定义条件下使用任何类型的代理功能?
- prestashop - 在 prestashop 的购物车页面中添加其他项目
- elasticsearch - Elasticsearch geo_shape查询:查找相交/在给定圆内的多边形
- android - 如何在 Kotlin 中设置 Toast 的重力(属性样式)(出现错误)?
- python - 在 seaborn 中更改轴以使用对数刻度