1

I am trying to persist entities with @OneToMany and @ManyToOne relationships for this db:

Database schema

Here is entities that was created by me:
Anime table:

@Entity
@Table(name = "anime")
public class Anime {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "user_id")
   private Integer animeId;

   @Column(name = "anime_name")
   private String animeName;

   @Column(name = "number_of_episodes")
   private Integer numberOfEpisodes;

   @Column(name = "general_rating")
   private Double generalRating;

   @Column(name = "number_of_votes")
   private Integer numberOfVotes;

   @OneToMany(mappedBy = "anime")
   private Set<UserRating> userRatings = new HashSet<>();

   //getters and setters
 }

Users table:

@Entity
@Table(name = "users")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Integer userId;

    @Column(name = "name")
    private String name;

    @Column(name = "password")
    private String password;

    @Column(name = "email")
    private String email;

    @OneToMany(mappedBy = "user")
    private Set<UserRating> userRatings = new HashSet<>();
   //getters and setters
}

And user ratings table and embedded id:

@Entity
@Table(name = "user_ratings")
public class UserRating {
@Embeddable
public static class UserRatingId implements Serializable{
    @ManyToOne
    @JoinColumn(name = "user_id")
    protected Integer userId;

    @ManyToOne
    @JoinColumn(name = "anime_id")
    protected Integer animeId;

    public UserRatingId() {
    }

    public UserRatingId(Integer userId, Integer animeId) {
        this.userId = userId;
        this.animeId = animeId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserRatingId that = (UserRatingId) o;
        return Objects.equals(userId, that.userId) &&
                Objects.equals(animeId, that.animeId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userId, animeId);
    }
}

@EmbeddedId
private UserRatingId id;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;

@ManyToOne
@JoinColumn(name = "anime_id")
private Anime anime;

@Column(name = "rating")
private Double rating;
   //getters and setters
}

Okay, so having all this entities and relationships defined as you see, I see NullPointerException that tells me that I messed up with foreign keys.

Root Cause

java.lang.NullPointerException
org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1749)
org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1658)

but I cannot understand how to fix. Could you please look at it and help me to find out where I messed up so I could fix it? Thank you.

Ann
  • 57
  • 3
  • 9

1 Answers1

2

You might try using derived identities. You would map your entities like this:

@Entity
@Table(name = "user_ratings")
public class UserRating {

    @Embeddable
    public static class UserRatingId implements Serializable {
        protected Integer userId; // type matches User's primary key
        protected Integer animeId; // type matches Anime's primary key
        //...
    }

    @EmbeddedId
    private UserRatingId id;

    @MapsId("userId") // maps userId attribute of embedded id
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @MapsId("animeId") // maps animeId attribute of embedded id
    @ManyToOne
    @JoinColumn(name = "anime_id")
    private Anime anime;

    //...
}

Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.

Brian Vosburgh
  • 3,146
  • 1
  • 18
  • 18