【发布时间】:2021-01-11 20:39:30
【问题描述】:
我有一个使用通用一对多关系的实体。不幸的是,lobmok @AllArgsConstructor 无法映射/投射 List 扩展为 List
无法将 java.lang.Long 字段 EducationTranslation.id 设置为 可翻译
是否有注释或设计模式可以让我摆脱自己编写的构造函数并保持代码更简洁更短?
@OneToMany(
targetEntity = EducationTranslation.class,
cascade = CascadeType.ALL,
fetch = FetchType.LAZY)
private List<? extends Translatable> translationList = new ArrayList<>();
public Education(Long id, Profile profile, Collection<? extends Translatable> translationList) {
this.id = id;
this.profile = profile;
this.translationList = translationList
.stream()
.map(x -> new EducationTranslation(x.getId(), x.getCode(), x.getTranslation()))
.collect(Collectors.toList());
}
【问题讨论】:
-
(1) “无法设置字段”错误是 JPA 抱怨它无法使用反射读取/填充
EducationTranslation的id属性。我非常怀疑这与Education的构造函数有什么关系,(2) 你确实意识到你永远无法将任何东西插入声明为List<? extends Translatable>的列表中,对吧? -
关于(2)这是由于对象的未知内存大小造成的吗?我认为设置 targetEntity 会设置内存大小
-
不,那是因为泛型是如何工作的。声明指出:“这是扩展
Translatable的某种类型的对象列表”。您不能向这样的列表插入任何内容,因为编译器不知道该列表接受哪种特定类型的对象。如果没有强制转换,列表一旦被分配就会变成有效的只读 -
好吧,我没有插入“任何东西”。我的 EducationTranslation 扩展了 Translatable。我有点通过我的流迭代做一个演员。
-
是的,您的流管道会生成一个
List<EducationTranslation>。然后将其分配给List<? extends Translatable>类型的属性。在此之后,translationList.add(<anything>)将产生一个编译错误,不管你用什么代替<anything>。这很好,因为您的管道无论如何都会生成一个不可变的列表,但是如果您保存实体,从数据存储中加载它并尝试添加一个元素,您会仍然得到一个编译错误。只是想确保您知道这一点
标签: hibernate jpa constructor annotations lombok