JPA级联持久性错误与已持久的实体

时间:2015-08-10 19:32:08

标签: java-ee jpa jpql persistence-manager

我在尝试更新实体时遇到了错误。 The solution to this problem说"拥有"在坚持所有者之前必须坚持实体,但我这样做了。或者用级联标记两个实体。

错误(我想不需要完整的堆栈跟踪):

2015-08-10T20:45:11.481+0200|Warning: A system exception occurred during an invocation on EJB ThreadLookUpService, method: public void main.java.services.ThreadLookUpService.setLastPost(long,main.java.entities.Post)
Caused by: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: main.java.entities.Post@6724f919.

(如果我添加cascade = CascadeType.ALL我收到另一个错误,告诉我外键不存在,但我只是坚持它。据我所知,我甚至不应该使用如果我以正确的顺序坚持实体,则级联。

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`forumcs`.`thethreads`, CONSTRAINT `fk_thethreads_posts1` FOREIGN KEY (`last_post`) REFERENCES `posts` (`idpost`) ON DELETE NO ACTION ON UPDATE NO ACTION)

在这里,我坚持发帖(拥有),然后是Thethread(所有者):

post = postLookup.createPostAndGiveItBack(post);
threadLookup.setLastPost(thread.getThread().getIdthread(), post); //this gives error.

这是我保留帖子的方法,我使用了flush因为我认为帖子ID没有生成或者smtg:

@Override
public Post createPostAndGiveItBack(Post post) {
    em.persist(post);
    em.flush();
    return post;
}

这是我更新Thethread的lastPost的方法。我可以直接将它与我之前提取的那个合并但是如果我这样做那么我的upvote和downvote字段将被弄乱,如果2个不同的用户观看同一页面并更新线程:

@Override
public void setLastPost(long id, Post post) {
    Query query = em.createQuery(FIND_THREAD_BY_ID);
    query.setParameter("id", id);
    Thethread thread = (Thethread) query.getSingleResult();
    thread.setLastPost(post);
}

发布实体:

@Entity
@Table(name = "posts")
@NamedQuery(name = "Post.findAll", query = "SELECT p FROM Post p")
public class Post implements Serializable, Comparable<Post> {
    private static final long serialVersionUID = 1L;

    @Id
    private int idpost;

    private String content;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "date_post")
    private Date datePost;

    private int downvotes;

    private int upvotes;

    // bi-directional many-to-one association to PostVote
    @OneToMany(mappedBy = "post")
    private List<PostVote> postVotes;

    // bi-directional many-to-one association to Post
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "reply_to_post")
    private Post replyTo;

    // bi-directional many-to-one association to Post
    @OneToMany(mappedBy = "replyTo")
    private List<Post> replies;

    // bi-directional many-to-one association to Thethread
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "threads_idthread")
    private Thethread thethread;

    // bi-directional many-to-one association to User
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "users_username")
    private User user;

    @Transient
    private double confidenceScore;

    public Post() {
    }

Thethread Entity:

@Entity
@Table(name = "thethreads")
@NamedQuery(name = "Thethread.findAll", query = "SELECT t FROM Thethread t")
public class Thethread implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private int idthread;

    private String content;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "date_posted")
    private Date datePosted;

    // I could get this by scanning the Threadvotes and count the number of downvotes
   // But I thought it was better like this for ease and performance.
    private int downvotes;

    @Column(name = "hot_score")
    private int hotScore;

    @Column(name = "is_pol")
    private String isPol;

    private String title;

    private String type;

    private int upvotes;

    // bi-directional many-to-one association to Post
    @OneToMany(mappedBy = "thethread")
    private List<Post> posts;

    // bi-directional many-to-one association to Category
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "categories_idcategory")
    private Category category;

    // UNI-directional many-to-one association to Post
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "last_post")
    private Post lastPost;

    // bi-directional many-to-one association to User
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "posted_by")
    private User user;

    // bi-directional many-to-one association to ThreadVote
    @OneToMany(mappedBy = "thethread")
    private List<ThreadVote> threadVotes;

1 个答案:

答案 0 :(得分:1)

我将此添加到我的实体ID:

@GeneratedValue(strategy = GenerationType.IDENTITY) 

它有效。