Я пытаюсь реализовать однонаправленные отношения «многие ко многим» между сущностями с пружиной + JPA.
после нескольких попыток изменить спящие версии, я не знаю, в чем причина
Вызвано: org.springframework.orm.jpa.JpaSystemException: Ошибка доступа к полю [private java.lang.Integer com.uca.refactor2.model.Achievement.id] из-за отражения для постоянного свойства [com.uca.refactor2. model.Achievement # id]: 1; вложенным исключением является org.hibernate.property.access.spi.PropertyAccessException: ошибка доступа к полю [private java.lang.Integer com.uca.refactor2.model.Achievement.id] отражением для постоянного свойства [com.uca.refactor2.model .Achievement # id]: 1
User.java
@Entity
@Table(name="USER")
public class User implements Serializable {
private static final long serialVersionUID = 4402583037980335445L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String firstName;
private String lastName;
@Column(unique = true)
private String username;
private String password;
@Enumerated(EnumType.STRING)
private UserType userType;
@OneToMany(cascade=CascadeType.ALL, mappedBy="joinedUserAchievementId.user")
private List<JoinedUserAchievement> joinedUserAchievementList = new ArrayList<JoinedUserAchievement>();
public User() {}
public User(Integer id) {
this.id = id;
}
public User(String username, String firstName, String lastName,
String password, UserType userType) {
this.username = username;
this.firstName = firstName;
this.lastName = lastName;
this.password = password;
this.userType = userType;
}
public List<JoinedUserAchievement> getAllAchievement() {
return joinedUserAchievementList;
}
public void addAchievement(Achievement achievement) {
// Notice a JoinedUserAchievement object
Date dateOfAcquisition = new Date();
JoinedUserAchievement joinedUserAchievement = new JoinedUserAchievement(new JoinedUserAchievement.JoinedUserAchievementId(this, achievement),dateOfAcquisition );
joinedUserAchievement.setAchievementId(achievement.getId());
joinedUserAchievementList.add(joinedUserAchievement);
}
//set and gets
JoinedUserAchievement.java
@Entity
@Table(name="USER_ACHIEVEMENT")
public class JoinedUserAchievement {
public JoinedUserAchievement() {}
public JoinedUserAchievement(JoinedUserAchievementId joinedUserAchievementId, Date dateOfAcquisition) {
this.joinedUserAchievementId = joinedUserAchievementId;
this.dateOfAcquisition = dateOfAcquisition;
}
@ManyToOne(targetEntity = Achievement.class)
@JoinColumn(name="id", insertable=false, updatable=false)
private Integer achievementId;
private Date dateOfAcquisition;
public String getDate() {
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = dateOfAcquisition;
return dateFormat.format(date);
}
public Integer getAchievementId() {
return achievementId;
}
public void setAchievementId(Integer achievementId) {
this.achievementId = achievementId;
}
@EmbeddedId
private JoinedUserAchievementId joinedUserAchievementId;
// required because JoinedUserAchievments contains composite id
@Embeddable
public static class JoinedUserAchievementId implements Serializable {
/**
*
*/
private static final long serialVersionUID = -9180674903145773104L;
@ManyToOne
@JoinColumn(name="USER_ID")
private User user;
@ManyToOne
@JoinColumn(name="ACHIEVEMENT_ID")
private Achievement achievement;
// required no arg constructor
public JoinedUserAchievementId() {}
public JoinedUserAchievementId(User user, Achievement achievement) {
this.user = user;
this.achievement = achievement;
}
public JoinedUserAchievementId(Integer userId, Integer achievementId) {
this(new User(userId), new Achievement(achievementId));
}
public User getUser() {
return user;
}
public Achievement getAchievement() {
return achievement;
}
public void setUser(User user) {
this.user = user;
}
public void setAchievement(Achievement achievement) {
this.achievement = achievement;
}
@Override
public boolean equals(Object instance) {
if (instance == null)
return false;
if (!(instance instanceof JoinedUserAchievementId))
return false;
final JoinedUserAchievementId other = (JoinedUserAchievementId) instance;
if (!(user.getId().equals(other.getUser().getId())))
return false;
if (!(achievement.getId().equals(other.getAchievement().getId())))
return false;
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 47 * hash + (this.user != null ? this.user.hashCode() : 0);
hash = 47 * hash + (this.achievement != null ? this.achievement.hashCode() : 0);
return hash;
}
}
}
Achievement.java
@Entity
@Table(name="ACHIEVEMENT")
public class Achievement implements Serializable{
private static final long serialVersionUID = 7747630789725422177L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer points;
public Achievement() {
}
public Achievement(String name, Integer points) {
this.name = name;
this.points = points;
}
public Achievement(Integer id) {
this.id = id;
}
//set and gets
Я также пытался сделать эти отношения двунаправленными, и они не работали, поэтому я могу что-то упустить
также до этого у меня были объекты Achivement вместо achivementId на joinUserAchievement, он работал, но я думаю, что это не то, что мне нужно, мне не нужно получать каждый объект достижения всегда, только с идентификатором в порядке.