Доступ к полю ошибки системной исключения JPA - PullRequest
0 голосов
/ 01 июля 2018

Я пытаюсь реализовать однонаправленные отношения «многие ко многим» между сущностями с пружиной + 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, он работал, но я думаю, что это не то, что мне нужно, мне не нужно получать каждый объект достижения всегда, только с идентификатором в порядке.

1 Ответ

0 голосов
/ 01 июля 2018

Из документов :

Отображения отношений, определенные во встроенном классе идентификаторов, не поддерживаются

Вы должны поместить идентификаторы только в JoinedUserAchievementId, и поставить User и Achievement ассоциации в JoinedUserAchievement прямо так:

public class JoinedUserAchievementId {

    private Long userId;
    private Long achievementId;
    ...
}

public class JoinedUserAchievement {

    @EmbeddedId
    private JoinedUserAchievementId joinedUserAchievementId;

    @ManyToOne
    @MapsId("userId")
    @JoinColumn(name = "USER_ID")
    private User user;

    @ManyToOne(optional = false, fetch = LAZY)
    @MapsId("achievementId")
    @JoinColumn(name = "ACHIEVEMENT_ID")
    private Achievement achievement;

    //if you absolutely need to map the achievement_id column here as well
    //note that it will already be mapped to joinedUserAchievementId.achievementId
    @Column(name = "ACHIEVEMENT_ID", insertable=false, updatable=false)
    private Long achievementId;
    ...
}

Не забудьте обновить отображение User.joinedUserAchievementList до mappedBy="user".

...