首页 > 解决方案 > 无法通过一对多关系保留子条目

问题描述

我有 3 个实体,一个是用户:

@Entity
@Table(name = "Users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "schoolId", referencedColumnName = "id", nullable = false)
    private School school;

    @Column(name = "emailAddress", nullable = false, unique=true)
    private String emailAddress;

    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "pwd", nullable = false)
    private String password;

    @Column(name = "role", nullable = false)
    private int role;

    @ManyToMany(fetch=FetchType.EAGER, cascade = { CascadeType.ALL })
    @JoinTable(name = "Enrollment", joinColumns = { @JoinColumn(name = "userId") }, inverseJoinColumns = {
            @JoinColumn(name = "courseId") })
    private Set<Course> courses;

    @OneToMany(fetch=FetchType.EAGER, mappedBy = "user", cascade = { CascadeType.ALL })
    private Set<Post> posts;
    ...

一是课程:

@Entity
@Table(name = "Courses")
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "schoolId", referencedColumnName = "id", nullable = false)
    private School school;

    @Column(name = "code", nullable = false)
    private String code;

    @Column(name = "name", nullable = false)
    private String name;

    @ManyToMany(fetch=FetchType.EAGER, cascade = { CascadeType.ALL })
    @JoinTable(name = "Enrollment", joinColumns = { @JoinColumn(name = "courseId") }, inverseJoinColumns = {
            @JoinColumn(name = "userId") })
    private Set<User> users;

    @OneToMany(fetch=FetchType.EAGER, mappedBy = "course", cascade = { CascadeType.ALL })
    private Set<Post> posts;
    ...

和发布:

@Entity
@Table(name = "Posts")
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "courseId", referencedColumnName = "id", nullable = false)
    private Course course;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "userId", referencedColumnName = "id", nullable = false)
    private User user;

    @Column(name = "title", nullable = false)
    private String title;

    @Column(name = "content")
    private String content;

    @Column(name = "views", nullable = false)
    private int views;

    @Column(name = "importance", nullable = false)
    private int importance;

    @Column(name = "createdAt", nullable = false)
    private Date createdAt;

    @Column(name = "updatedAt")
    private Date updatedAt;
    ...

它们之间的关系是:

帖子 - n:1 -> 课程

帖子 - n:1 -> 用户

我要做的是在数据库中添加一个新帖子并更新相关的课程和用户条目。下面是我的代码:

Configuration configuration = new Configuration();
        configuration.configure("hibernate.cfg.xml");
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        User user = session.load(User.class, (Integer) this.session.get("userId"));
        Course course = session.load(Course.class, (Integer) this.session.get("courseId"));
        Post post = new Post();
        post.setContent(content);
        post.setCreatedAt(new Date());
        post.setTitle(title);
        post.setViews(0);
        post.setImportance(0);
        user.getPosts().add(post);
        course.getPosts().add(post);
        session.persist(user);
        session.persist(course);
        transaction.commit();
        session.close();
        sessionFactory.close();

当代码执行时,这是我得到的错误:

1:非空属性引用空值或瞬态值:com.qury.models.Post.course

2:org.hibernate.PropertyValueException:非空属性引用空值或瞬态值:com.qury.models.Post.course

我哪里弄错了?我也应该设置帖子实体的用户和课程属性吗?

标签: hibernateone-to-manymany-to-one

解决方案


很简单——瞬态值意味着还不是数据库一部分的东西。这些通常是新创建的对象,就像您的Post post = new Post();那样,所以不要将这些瞬态对象添加到其他实体的列表中,只需添加从数据库返回的其他实体,因此不会瞬态到 Post 实体。

换句话说,转这个:

user.getPosts().add(post);
course.getPosts().add(post);
session.persist(user);
session.persist(course);

进入这个:

post.setUser(user);
post.setCourse(course);
session.persist(post);

推荐阅读