0

I am trying Spring data jpa implementation using CrudRepository. Below is my Entity 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;
  }

}

And have a repository as below,

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

And trying to use h2 database for local testing

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

And from the CommandLineRunner calling the save method of the UserRepository, but getting below error,

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]

Andronicus
  • 25,419
  • 17
  • 47
  • 88
Pradeep
  • 350
  • 1
  • 3
  • 13

3 Answers3

2

Hibernate supports three data mapping types: basic (e.g String, int), Embeddable and Entity. Most often, a database row is mapped to an Entity, each database column being associated to a basic attribute. Embeddable types are more common when combining several field mappings into a reusable group (the Embeddable being merged into the owning Entity mapping structure).

Both basic types and Embeddables can be associated to an Entity through the @ElementCollection, in a one-Entity-many-non-Entity relationship.

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

So you need to remove @OneToMany as OneToMany is for one-Entity-many-Entity relationship. If you want to map to an Entity, then need change the code like below and create a new Entity Photo.

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

In the above code , Photo is an Entity.

see the below link for more information: https://vladmihalcea.com/how-to-optimize-unidirectional-collections-with-jpa-and-hibernate/

Gundamaiah
  • 780
  • 2
  • 6
  • 30
0

You are not using Entity model for storing photo urls.

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

So you need to remove @OneToMany.

AConsumer
  • 2,461
  • 2
  • 25
  • 33
0

You don't need @OneToMany, @ManyToOne, @OneToOne or @ManyToMany annotation unless there are relationships between tables so remove @OneToMany since there is no relationship in your case.

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;
      }
    
    }
Zishan Khan
  • 167
  • 6