【问题标题】:Use of @OneToMany or @ManyToMany targeting an unmapped class for List<String> in Spring data jpa在 Spring 数据 jpa 中使用 @OneToMany 或 @ManyToMany 针对 List<String> 的未映射类
【发布时间】:2020-10-24 02:43:45
【问题描述】:

我正在尝试使用 CrudRepository 实现 Spring data jpa。 下面是我的实体类

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 的 save 方法,但得到以下错误,

原因:org.hibernate.AnnotationException:使用@OneToMany 或@ManyToMany 定位未映射的类:model.User.photoUrls[java.lang.String] 在 org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1191) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 在 org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:794) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]

【问题讨论】:

标签: java spring spring-boot hibernate hibernate-mapping


【解决方案1】:

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

基本类型和 Embeddables 都可以通过 @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<>();

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

查看以下链接了解更多信息: https://vladmihalcea.com/how-to-optimize-unidirectional-collections-with-jpa-and-hibernate/

【讨论】:

  • @Pradeep 接受此答案,如果它解决了您的问题。
【解决方案2】:

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

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

所以你需要删除@OneToMany。

【讨论】:

    【解决方案3】:

    除非表之间存在关系,否则您不需要 @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;
          }
        
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-08
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      相关资源
      最近更新 更多