gpt4 book ai didi

java - JPA 添加子记录 - 在父记录中有 3 个副本

转载 作者:行者123 更新时间:2023-12-01 11:26:18 24 4
gpt4 key购买 nike

我有新闻实体和评论实体。我想创建有 0 条评论的新闻,然后向该新闻添加一些评论。

在数据库中,我有用于新闻信息的表 NEWS 和 COMMENTS 表中的 news_id 列。

新闻.java:

@Entity
@Table(name = "NEWS")
public class News implements Serializable{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 883279937885116359L;
/**
* News id
*/
@Id
@GeneratedValue(generator = "seq")
@SequenceGenerator(name="seq", sequenceName="NEWS_SEQ",allocationSize=1)
@Column(name = "NEWS_ID", nullable = false, unique = true)
private Long id;
/**
* News short text
*/
@Column(name = "SHORT_TEXT")
private String shortText;
/**
* News full text
*/
@Column(name = "FULL_TEXT")
private String fullText;
/**
* News title
*/
@Column(name = "TITLE")
private String title;
/**
* News creation date
*/
@Column(name = "CREATION_DATE")
private Date creationDate;
/**
* News modification date
*/
/**
* News comments
*/
@OneToMany(cascade = CascadeType.ALL, orphanRemoval= true, fetch = FetchType.EAGER)
@JoinColumn(name = "NEWS_ID")
private List<Comment> comments;

评论.java:

@Entity
@Table(name = "COMMENTS")
public class Comment implements Serializable{
/**
* serialVersionUID
*/
private static final long serialVersionUID = -5697896094322498108L;
/**
* Comment id
*/
@Id
@GeneratedValue(generator = "seq")
@SequenceGenerator(name="seq", sequenceName="COMMENTS_SEQ",allocationSize=1)
@Column(name = "COMMENT_ID", nullable = false, unique = true)
private Long id;
/**
* Comment text
*/
@Column(name = "COMMENT_TEXT")
private String commentText;
/**
* Comment creation date
*/
@Column(name = "CREATION_DATE")
private Date creationDate;
/**
* Id of the news which the comment is added to
*/
@Column(name = "NEWS_ID")
private Long newsId;

我有这样的代码:

            News news = new News();

news.setTitle("qwerty");
news.setShortText("qwerty");
news.setFullText("qwerty");

jpaNewsDAO.add(news);
news = jpaNewsDAO.findById(news.getId());//everything is fine here
// 0 comments
Comment comment = new Comment(null,"qwerty",new Date(),news.getId());
jpaCommentDAO.add(comment);
news = jpaNewsDAO.findById(news.getId());

但是在那之后,news.comments 有 3 个项目,其中包含评论的副本(即使具有相同的 id),我不明白为什么。 DB中只有一条这样的评论。

添加评论:

@Override
public Long add(Comment entity) throws DAOException {
EntityManager manager = null;
EntityTransaction transaction;
try {
manager = managerFactory.createEntityManager();
transaction = manager.getTransaction();
transaction.begin();
entity.setId(null);
manager.persist(entity);
manager.flush();
transaction.commit();
} catch (PersistenceException e) {
throw new DAOException(e);
} finally {
closeManager(manager);
}
return entity.getId();
}

添加新闻:

@Override
public Long add(News entity) throws DAOException {
EntityManager manager = null;
EntityTransaction transaction;
try {
manager = managerFactory.createEntityManager();
transaction = manager.getTransaction();
transaction.begin();
entity.setId(null);

List<Comment> comments = new ArrayList<Comment>();
if (entity.getComments()!= null) {
for (Comment comment : entity.getComments()) {
comments.add(manager.find(Comment.class, comment.getId()));
}
}
entity.setComments(comments);

manager.persist(entity);//add
manager.flush();
transaction.commit();
} catch (PersistenceException e) {
throw new DAOException(e);
} finally {
closeManager(manager);
}
return entity.getId();
}

那为什么我有评论副本?

最佳答案

该问题是由于新闻和评论之间的关系被标记为 EAGER 造成的。有关为什么会出现这种情况的更多信息,请参阅此处:

Hibernate Criteria returns children multiple times with FetchType.EAGER

您可以将关系标记为 LAZY,这样可以防止出现问题。通常,最佳实践是以这种方式定义关系,并通过查询提示或 JPA 2.1 的新“实体图”功能等方式根据给定用途的需要启用预先获取关系。

https://blogs.oracle.com/theaquarium/entry/jpa_2_1_entity_graphs

现在您只需在 DAO 中添加以下行即可:

news.getComments().size()。

这将强制加载惰性集合。然后它显然将在您的网络层中可用。

关于java - JPA 添加子记录 - 在父记录中有 3 个副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30777126/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com