I'm creating a social media website with spring and I have a problem with composite primary keys. I have User, Post and PostLike tables and I need to keep track of which user liked which posts. I also have a UserData and Post relation which tells me the posts author, but that isn't causing any problems. Basically, my PostLike table should contain post_id and user_id columns and they should serve as a composite primary key.
I have attempted to do this by creating a PostLikeId embeddable:
My PostLikeId class:
@Embeddable
public class PostLikeId implements Serializable {
@Column(name = "post_id")
private Post post;
@Column(name = "user_id")
private UserData user;
// getters and setters
}
My PostLike class:
@Entity
@Table(name = "post_like")
public class PostLike {
@EmbeddedId
private PostLikeId id;
//getters and setters
}
My Post class:
@Entity
@Table(name = "post")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_id_seq_generator")
@SequenceGenerator(name = "post_id_seq_generator", sequenceName = "post_id_seq", allocationSize = 10)
@Column(name = "id", updatable = false)
private Long id;
@OneToMany(cascade = CascadeType.ALL,
orphanRemoval = true
)
@JoinColumns({
@JoinColumn(name = "post_id",
referencedColumnName = "post_id"),
@JoinColumn(name = "user_id",
referencedColumnName = "user_id")
})
private List<PostLike> likes = new ArrayList<>();
}
... and my UserData class:
@Entity
@Table(name = "user_data")
public class UserData {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_data_id_seq_generator")
@SequenceGenerator(name = "user_data_id_seq_generator", sequenceName = "user_data_id_seq", allocationSize = 10)
@Column(name = "id", updatable = false)
private Long id;
@OneToMany(
mappedBy = "user",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Post> posts = new ArrayList<>();
@OneToMany(
mappedBy = "id",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostLike> likedPosts = new ArrayList<>();
When I attempt to run and map this, I get the following exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to map collection com.budano.SocialStudent.model.Post.likes
.
.
.
Caused by: org.hibernate.AnnotationException: Unable to map collection com.budano.SocialStudent.model.Post.likes
.
.
.
Caused by: org.hibernate.cfg.RecoverableException: Unable to find column with logical name: post_id in org.hibernate.mapping.Table(public.post) and its related supertables and secondary tables
Can someone please explain what this log is telling me and how should I approach this problem? Thank you!
This is an approach you might try:
PostLikeId:
@Embeddable
public class PostLikeId implements Serializable {
@Column(name = "post_id")
private Long postId; // corresponds to PK type of Post
@Column(name = "user_id")
private Long userId; // corresponds to PK type of User
// ...
}
PostLike:
@Entity
@Table(name = "post_like")
public class PostLike {
@EmbeddedId
private PostLikeId id;
@MapsId("postId") // maps postId attribute of embedded id
@ManyToOne
private Post post;
@MapsId("userId") // maps userId attribute of embedded id
@ManyToOne
private UserData user;
// ...
}
Post:
@Entity
@Table(name = "post")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_id_seq_generator")
@SequenceGenerator(name = "post_id_seq_generator", sequenceName = "post_id_seq", allocationSize = 10)
@Column(name = "id", updatable = false)
private Long id;
@ManyToOne
private UserData user;
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PostLike> likes = new ArrayList<>();
// ...
}
UserData:
@Entity
@Table(name = "user_data")
public class UserData {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_data_id_seq_generator")
@SequenceGenerator(name = "user_data_id_seq_generator", sequenceName = "user_data_id_seq", allocationSize = 10)
@Column(name = "id", updatable = false)
private Long id;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> posts = new ArrayList<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PostLike> likedPosts = new ArrayList<>();
// ...
}
Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.