问题描述
我有两个实体User和Focus,我必须为其存储一个等级,这样一个User才能具有多个Focus的排名,并且一个Focus可能有许多用户。为了解决这个问题,我遵循了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。如果用户未进行评级,则会遇到问题一个等级,则该等级的集合为空,而不是每个存在的焦点的等级为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添加到评级实体:
@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,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;
}
}
}