使用 @OneToMany 或 @ManyToMany 为 Spring 数据 jpa 中的 List<String> 定位未映射的 class

Use of @OneToMany or @ManyToMany targeting an unmapped class for List<String> in Spring data jpa

我正在尝试 Spring 使用 CrudRepository 实现数据 jpa。 下面是我的实体 Class

public class User {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Long id = null;

  @OneToMany
  @ElementCollection
  @CollectionTable(name="photoUrls")
  @Valid
  private List<String> photoUrls = new ArrayList<String>();

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }
  public List<String> getPhotoUrls() {
    return photoUrls;
  }

  public void setPhotoUrls(List<String> photoUrls) {
    this.photoUrls = photoUrls;
  }

}

并且有如下的存储库,

public interface UserRepository extends CrudRepository<User, Long>{
  
}

并尝试使用h2数据库进行本地测试

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

并且从 CommandLineRunner 调用 UserRepository 的保存方法,但出现以下错误,

Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: model.User.photoUrls[java.lang.String] at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1191) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:794) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]

Hibernate 支持三种数据映射类型:基本(例如 String、int)、Embeddable 和 Entity。大多数情况下,数据库行映射到实体,每个数据库列关联到一个基本属性。将多个字段映射组合到一个可重用组中时,可嵌入类型更为常见(Embeddable 被合并到拥有的 Entity 映射结构中)。

基本类型和可嵌入对象都可以通过 @ElementCollection 在一个实体-多个非实体关系中关联到一个实体。

  @ElementCollection
  @CollectionTable(name="photoUrls",
                   joinColumns = @JoinColumn(name =  "user_id"))
  @Valid
  private List<String> photoUrls = new ArrayList<String>();

因此您需要删除 @OneToMany,因为 OneToMany 用于一个实体与多个实体的关系。如果你想映射到一个实体,那么需要像下面这样更改代码并创建一个新的实体照片。

@OneToMany(
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
private List<Photo> photos = new ArrayList<>();

在上面的代码中,照片是一个实体。

有关详细信息,请参阅下面的 link: https://vladmihalcea.com/how-to-optimize-unidirectional-collections-with-jpa-and-hibernate/

没有使用实体模型存储照片网址。

@ElementCollection annotation is used to store a list of values as an entity attribute without needing to model an additional entity.

所以你需要删除@OneToMany。

您不需要 @OneToMany@ManyToOne@OneToOne@ManyToMany 注释,除非表之间存在关系,因此删除 @OneToMany 因为有你的情况没有任何关系。

public class User {
      @Id
      @GeneratedValue(strategy=GenerationType.AUTO)
      private Long id = null;
    
      @ElementCollection
      @CollectionTable(name="photoUrls")
      @Valid
      private List<String> photoUrls = new ArrayList<String>();
    
      public Long getId() {
        return id;
      }
    
      public void setId(Long id) {
        this.id = id;
      }
      public List<String> getPhotoUrls() {
        return photoUrls;
      }
    
      public void setPhotoUrls(List<String> photoUrls) {
        this.photoUrls = photoUrls;
      }
    
    }