我有以下问题:我有三个连接的类。我已经为它们添加了注释,但结果却是错误的(如下所述):

@Entityd
@Table(name = "ClassA")
public class ClassA{
    @Id
    @GeneratedValue
    private Long id = 0L;
    ...
    @OneToMany(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
    @Fetch(FetchMode.SELECT)
    @Column(name = "ClassBList")
    private List<ClassB> listB;
    ...
}

@Entity
@Table(name="ClassB")
public class ClassB {
     @Id
     @GeneratedValue
     private Long id = 0L;
     ...
     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
     @Fetch(FetchMode.SELECT)
     @Column(name = "ClassCList")
     private List<ClassC> listC;
     ...
}

@Entity
@Table(name="ClassC")
public class ClassC  {
  @Id
  @GeneratedValue()
  private Long id = 0L;
  ...
  @ElementCollection
  private List<String> listD;
  ...
}


当我为第一个ClassA使用这种结构时,我创建,保存和加载一切正常。对于我保存以供回购和再次加载的ClassA的新实例,我突然在listD中有了第一个ClassA的字符串。

我需要的结果是每个类都“独立”保存。因此,每个类的集合应包含唯一的对象(每个类都有其自己的ID和子列表)。

使用Spring Boot 2.2.0.M5和javax.persistence-api 2.2在Java 8中为此类建模的最佳方法(注释)是什么?

编辑:

我现在删除了B类,并将A类重写为:

@Entity
@Table(name = "ClassA")
public class ClassA{
    @Id
    @GeneratedValue
    private Long id = 0L;
    ...
    @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = CascadeType.ALL)
    @MapKey(name = "type")
    private Map<String,Set<ClassC>> classCmap;
    ...
}


这给我一个错误,如:

org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class


我如何对此建模/解决/注释?

最佳答案

如果您不需要基于listD查询数据,我建议将列表作为文本保留在数据库中,并使用转换器:

@Converter
public class ListDConverter implements AttributeConverter<List<String>, String> {

 private ObjectMapper objectMapper = new ObjectMapper();

 @Override
 public String convertToDatabaseColumn(List<String> listD) {
     try {
       return objectMapper.writeValueAsString(listD);
     } catch(IOException e){
        return null;
     }
 }

 @Override
 public List<String> convertToEntityAttribute(String stringListD) {
     if(stringListD == null){
        return Collections.emptyList();
     }
     try {
        return objectMapper.readValue(stringListD, new TypeReference<List<String>>() {});
      }catch(IOException e){
        return Collections.emptyList();
     }
 }

}


并在您的ClassC实体类中:

@Convert(converter = ListDConverter.class)
private List<String> listD;


我为什么喜欢这种方法:


没有多余的表和联接=>更好的性能
更容易读取数据库中的listD

08-28 07:09