Hibernate 与构造函数的泛型一对多关系
我有一个使用通用一对多关系的实体。不幸的是,lobmok@allargsconstuctor无法映射/强制转换列表使用通配符约束的集合是。。。对于JPA实体来说有些不方便Hibernate 与构造函数的泛型一对多关系,hibernate,jpa,constructor,annotations,lombok,Hibernate,Jpa,Constructor,Annotations,Lombok,我有一个使用通用一对多关系的实体。不幸的是,lobmok@allargsconstuctor无法映射/强制转换列表使用通配符约束的集合是。。。对于JPA实体来说有些不方便 请注意,初始创建后,您将永远无法将任何内容插入声明为list(1)的列表中。“无法设置字段”错误为JPA,它抱怨无法使用反射读取/填充EducationTranslation的id属性。我非常怀疑这与教育的构造函数有关,(2)您确实意识到您将永远无法在声明为列表的列表中插入任何内容。关于(2)这是因为对象的内存大小未知吗?我认
请注意,初始创建后,您将永远无法将任何内容插入声明为
list(1)的列表中。“无法设置字段”错误为JPA,它抱怨无法使用反射读取/填充EducationTranslation
的id
属性。我非常怀疑这与教育的构造函数有关,(2)您确实意识到您将永远无法在声明为列表的列表中插入任何内容。关于(2)这是因为对象的内存大小未知吗?我认为设置targetEntity会设置内存大小,这是因为泛型是如何工作的。该声明声明声明:“这是扩展了可翻译的的某种类型的对象列表。”。您不能向这样的列表中插入任何内容,因为编译器不知道列表接受哪种特定类型的对象。如果不强制转换,列表将在分配后变为只读。好吧,我不插入“任何内容”。我的教育翻译是可翻译的。我通过我的流迭代进行了一些转换。是的,您的流管道生成了一个列表。然后将其分配给list类型的属性。非常感谢!尤其是狗猫变形者的例子选得非常好,当我意识到我的逻辑错误时,我笑了:D
@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());
}
Education education = entityManager.find(Education.class, id);
education.getTranslationList().add(new EducationTranslation(...)); // compilation error
List<Dog> dogs = new ArrayList<>(List.of(new Dog())); //just a mutable collection with a Dog inside
List<? extends Animal> someAnimals = dogs; //a list of Dogs is a list of 'a type that extends Animal', so - valid assignment
someAnimals.add(new Cat()); //hey, a Cat does extend Animal, so this should be legal, right?
Dog shapeshifter = dogs.get(1); //...right???
Object obj = "Hello";
obj.length(); // you know obj points to a String, but you assign it to a reference with a more general type, so this call is illegal
interface TranslationHolder {
List<? extends Translatable> getTranslationList();
}
class Education implements TranslationHolder {
private List<EducationTranslation> translationList = new ArrayList<>();
//this getter is a valid implementation for TranslationHolder.getTranslationList()
public List<EducationTranslation> getTranslationList() {
return translationList;
}
}
class ClassThatUsesEducationButOnlyKnowsItAsTranslationHolder {
public void execute() {
TranslationHolder holder = getEducationAsTranslationHolderInSomeIndirectWay();
holder.getTranslationList(); // this still return a reference to List<? extends Translatable>, NOT List<EducationTranslation>
}
}