双向一对多关系不起作用

时间:2012-01-14 11:30:41

标签: java java-ee jpa

我做了一个应用程序,显示了我的数据库中的很多问题。为此,我提出了一个问题实体。我希望能够“报告”一个穷人/好人等问题,所以为此我做了一个反馈实体。

这些之间的关系是:一个问题可能有很多反馈,一个反馈属于一个问题。

问题在于,当我保存问题反馈实例时,它完全映射到数据库中,但是当我打开一个问题并循环遍历所有反馈时,没有显示添加的反馈。为了显示它们,我需要重新部署Web应用程序。

为什么会这样?

为了便于阅读,我只展示所涉及的部分

问题反馈实体

public class QuestionFeedback implements Serializable {

    @ManyToOne
    private Question question;
    ....

    public void setQuestion(Question question) {
        this.question = question;

        if (!question.getFeedbacks().contains(this)) {
            question.getFeedbacks().add(this);
        }
    }
    ....
}

提问实体

@Entity
public class Question implements Serializable {

    @OneToMany(mappedBy = "question", fetch = FetchType.EAGER)
    private List<QuestionFeedback> feedbacks;

    public Question() {
        feedbacks = new ArrayList<QuestionFeedback>();
    }

    public void addFeedback(QuestionFeedback questionFeedback) {

        if (!getFeedbacks().contains(questionFeedback)) {
            getFeedbacks().add(questionFeedback);
        }

        if (questionFeedback.getQuestion() != this) {
            questionFeedback.setQuestion(this);
        }
    }
}

报告页面的支持bean

已从数据库中检索问题实体。

public String flag() {
    questionFeedback.setQuestion(question);
    questionFeedbackService.persist(questionFeedback);

    return "index";
}

DAO课程

public void persist(QuestionFeedback questionFeedback) {
    entityManager.persist(questionFeedback);
}

2 个答案:

答案 0 :(得分:2)

这是一个简单的脏会话实例。

虽然这些可能是由各种问题引起的,但通常要记住两个简单的事情,这样可以很容易地跟踪这个问题。

首先,您必须始终记住,当我们坚持我们在JPA / hibernate中的数据时,我们不一定有任何关于该事务已在数据库中完成的保证。 “持久”方法的真正含义是错误和问题的常见来源,确保您完全理解它以及它与业务逻辑的关系。 :

What's the advantage of persist() vs save() in Hibernate?

其次,在您完成事务已完成且数据已保存之后,您可以使用 EntityManager.refresh 方法更新数据库中任何对象的状态。

答案 1 :(得分:0)

您可以通过以下代码清除JPA缓存:

 em.getEntityManagerFactory().getCache().evictAll();

对于记录,我总是在持久数据后刷新。即使你的数据库有数据,我也会尝试这个。

public String flag() {
   questionFeedback.setQuestion(question);
   questionFeedbackService.persist(questionFeedback);
   questionFeedbackService.flush();

   return "index";
}