spring - Spring没有将复合键实体映射到数据库
问题描述
我有两个实体用户和焦点,我必须为其存储一个排名,以便用户可以对许多焦点进行排名,而一个焦点可能有很多用户。为了处理这个问题,我遵循了https://www.baeldung.com/jpa-many-to-many第 3 部分,其中我有以下 2 个类:
@Entity(name = "UserBaseRatings")
public class Rating {
@EmbeddedId
RatingKey id;
@ManyToOne
@MapsId("userID")
@JoinColumn(name="userID")
private User user;
@ManyToOne
@MapsId("focusID")
@JoinColumn(name="focusID")
private Focus focus;
private BigDecimal baseRating;
protected Rating(){}
public Rating(User user, Focus focus, BigDecimal baseRating) {
this.user = user;
this.focus = focus;
this.baseRating = baseRating;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Focus getFocus() {
return focus;
}
public void setFocus(Focus focus) {
this.focus = focus;
}
public BigDecimal getBaseRating() {
return baseRating;
}
public void setBaseRating(BigDecimal baseRating) {
this.baseRating = baseRating;
}
}
和
@Embeddable
public class RatingKey implements Serializable {
@Column(name="userID")
private Long userID;
@Column(name="focusID")
private Long focusID;
protected RatingKey(){}
public RatingKey(Long userID, Long focusID) {
this.userID = userID;
this.focusID = focusID;
}
public Long getUserID() {
return userID;
}
public void setUserID(Long userID) {
this.userID = userID;
}
public Long getFocusID() {
return focusID;
}
public void setFocusID(Long focusID) {
this.focusID = focusID;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RatingKey ratingKey = (RatingKey) o;
return Objects.equals(userID, ratingKey.userID) &&
Objects.equals(focusID, ratingKey.focusID);
}
@Override
public int hashCode() {
return Objects.hash(userID, focusID);
}
}
UserBaseRatings 表的 baseRating 的默认值为 1,这样如果用户对当前焦点没有评分,他们的评分应该是 1。我遇到了一个问题,如果用户没有评分,那么Rating 的集合是空的,而不是为每个存在的焦点评分 1。
用户:
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long userID;
@Column(name = "userHashedPassword")
private String password;
@Column(name = "userName")
private String userName;
@Column(name = "userEmail")
private String email;
//probably being reset
@Transient
private List<String> groups = new LinkedList<>();
@ManyToMany
@JoinTable(name = "UserRoles",
joinColumns = @JoinColumn(
name = "userID"),
inverseJoinColumns = @JoinColumn(
name = "roleID"))
private Set<Role> roles = new HashSet<>();
@OneToMany(mappedBy = "user")
private Set<Rating> ratings;
protected User(){}
public User(String userHashedPassword, String userName, String email, Set<Role> roles){
this.password = userHashedPassword;
this.userName = userName;
this.email = email;
this.roles = roles;
}
public Long getUserId() {
return userID;
}
public void setId(Long userID) {
this.userID = userID;
}
public String getPassword(){
return password;
}
public void setPassword(String password){
this.password = password;
}
public String getUsername() {
return userName;
}
public void setUsername(String name) {
this.userName = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public Set<Rating> getRatings() {
return ratings;
}
public void setRatings(Set<Rating> ratings) {
this.ratings = ratings;
}
}
重点:
@Entity
public class Focus {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long focusID;
private String focusCategory;
private String focusName;
private String focusExplanation;
@OneToMany(mappedBy = "focus")
Set<Rating> ratings;
//image
protected Focus(){}
public Focus(String focusCategory, String focusName, String focusExplanation, Set<Rating> ratings){
this.focusCategory = focusCategory;
this.focusName = focusName;
this.focusExplanation = focusExplanation;
this.ratings = ratings;
}
public Long getFocusId() {
return focusID;
}
public void setFocusId(Long focusID) {
this.focusID = focusID;
}
public String getFocusCategory() {
return focusCategory;
}
public void setFocusCategory(String focusCategory) {
this.focusCategory = focusCategory;
}
public String getFocusName() {
return focusName;
}
public void setFocusName(String focusName) {
this.focusName = focusName;
}
public String getFocusExplanation() {
return focusExplanation;
}
public void setFocusExplanation(String focusExplanation) {
this.focusExplanation = focusExplanation;
}
public Set<Rating> getRatings() {
return ratings;
}
public void setRatings(Set<Rating> ratings) {
this.ratings = ratings;
}
}
我缺少什么将允许用户的评级填充数据库中存在的每个焦点的默认值?
编辑:将 @PrePersist 和 @PreUpdate 添加到 Rating 实体:
@Entity(name = "UserBaseRatings")
public class Rating {
@EmbeddedId
RatingKey id;
@ManyToOne
@MapsId("userID")
@JoinColumn(name="userID")
private User user;
@ManyToOne
@MapsId("focusID")
@JoinColumn(name="focusID")
private Focus focus;
private BigDecimal baseRating;
protected Rating(){}
public Rating(User user, Focus focus, BigDecimal baseRating) {
this.user = user;
this.focus = focus;
this.baseRating = baseRating;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Focus getFocus() {
return focus;
}
public void setFocus(Focus focus) {
this.focus = focus;
}
public BigDecimal getBaseRating() {
return baseRating;
}
public void setBaseRating(BigDecimal baseRating) {
this.baseRating = baseRating;
}
@PrePersist
public void prePersist() {
if(baseRating == null) {
baseRating = BigDecimal.ONE;
}
}
@PreUpdate
public void preUpdate() {
if(baseRating == null) {
baseRating = BigDecimal.ONE;
}
}
}
spring.jpa.hibernate.ddl-auto=
从更改none
为update
也没有任何区别。
解决方案
如果您使用 ORM,则必须显式声明所有默认值。可以这样做
@Entity(name = "UserBaseRatings")
public class Rating {
// ...
private BigDecimal baseRating = BigDecimal.ONE;
// ...
}
或使用@PrePersist
和@PreUpdate
@Entity(name = "UserBaseRatings")
public class Rating {
// ...
private BigDecimal baseRating;
// ...
@PrePersist
public void prePersist() {
if(baseRating == null) {
baseRating = BigDecimal.ONE;
}
}
@PreUpdate
public void preUpdate() {
if(baseRating == null) {
baseRating = BigDecimal.ONE;
}
}
}
推荐阅读
- angular-material2 - Angular8 i18n for placeholderLabel 文本
- html - 根据 angular4 中选定的下拉项传递 ID
- reactjs - React 门户未显示在顶部
- javascript - Highstock 图表工具提示仅在图表内激活
- image - 谷歌搜索网址,用于按图片搜索
- visual-studio-2017 - Visual Studio 属性窗口渲染问题等
- installation - Arelle软件未安装
- c# - 如何将 XSI 类型添加到使用 LINQ 序列化的元素
- python - 从熊猫列python中给出的地址中仅提取城市和密码
- c# - 从 PostScript (CIP3) 文件中提取位图