【发布时间】:2020-06-09 15:51:51
【问题描述】:
我有具有多对多映射的用户和课程实体。连接表Registration 包含两个额外的字段,因此需要它自己的表。当我尝试保存用户时,出现以下错误。我不知道我哪里错了。
Caused by: org.hibernate.PropertyAccessException: Could not set field value [2] value by reflection : [class com.classpath.edukart.model.UserCourseId.courseId] setter of com.classpath.edukart.model.UserCourseId.courseId
at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:72) ~[hibernate-org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 37 common frames omitted
Caused by: java.lang.NullPointerException: null
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:57) ~[na:1.8.0_191]
at sun.reflect.UnsafeLongFieldAccessorImpl.set(UnsafeLongFieldAccessorImpl.java:75) ~[na:1.8.0_191]
at java.lang.reflect.Field.set(Field.java:764) ~[na:1.8.0_191]
at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:52) ~[hibernate-core-5.4.15.Final.jar:5.4.15.Final]
... 89 common frames omitted
User
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@EqualsAndHashCode(of = "userId")
@Builder
@Entity
public class User {
@Id
@GeneratedValue(strategy = AUTO)
private long userId;
@Column(nullable = false)
private String firstName;
private String lastName;
@Column(unique = true)
private String emailAddress;
@OneToMany(mappedBy = "user", cascade = ALL)
private Set<Registration> courses;
public void registerCourse(Course course){
Registration registration = new Registration(this, course);
if(course.getUsers() == null){
course.setUsers(new HashSet<>());
}
if (this.courses == null){
this.courses = new HashSet<>();
}
course.getUsers().add(registration);
this.courses.add(registration);
}
}
Course
@Entity
@Table(name = "courses")
@Setter
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = {"id", "name"})
@ToString(of = {"id", "name", "price","duration", "rating"})
public class Course {
@Id
@GeneratedValue(strategy = AUTO)
private long id;
private String name;
private double price;
private int duration;
private double rating;
@OneToMany(mappedBy = "course")
private Set<Registration> users;
}
Registration
@Entity
@Table(name = "users_courses")
@Setter
@Getter
@EqualsAndHashCode(of = {"user", "course"})
public class Registration {
@EmbeddedId
private UserCourseId id;
@ManyToOne(fetch = LAZY)
@MapsId("userId")
private User user;
@ManyToOne(fetch = LAZY)
@MapsId("courseId")
private Course course;
@Column(name = "registration_date")
private LocalDate registeredDate;
private int percentageCompleted;
private Registration(){}
public Registration(User user, Course course){
this.user = user;
this.course = course;
}
}
UserCourseId
@Embeddable
@EqualsAndHashCode
public class UserCourseId implements Serializable {
@Column(name="user_id")
private long userId;
@Column(name = "course_id")
private long courseId;
public UserCourseId(){}
public UserCourseId (long userId, long courseId){
this.userId = userId;
this.courseId = courseId;
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public long getCourseId() {
return courseId;
}
public void setCourseId(long courseId) {
this.courseId = courseId;
}
}
客户端程序
@Override
@Transactional
public void run(String... args) {
User johnDoe = User.builder()
.firstName("John")
.lastName("Doe")
.emailAddress("johndoe22@gmail.com")
.address(new HashSet<>()).build();
Course java = Course.builder().name("Java").duration(24).price(15_000).build();
Course python = Course.builder().name("Python").duration(14).price(25_000).build();
johnDoe.registerCourse(java);
// johnDoe.registerCourse(python);
userRepository.save(johnDoe);
log.info("Before saving to the db :: {}", johnDoe.getCourses());
}
【问题讨论】:
标签: hibernate jpa spring-data-jpa many-to-many