[英]How to handle large dataset with JPA (or at least with Hibernate)?
[英]How to handle large collections in hibernate
我有一个Entry实体和一个Comment实体。 Entry实体与Comment实体具有OneToMany关联:
@Entity
@Table(name="entries")
public class Entry {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@OneToMany(mappedBy = "entry", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.EXTRA)
private List<Comment> comments = new ArrayList<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<Comment> getComments() {
return comments;
}
public boolean containsComment(int commentId) {
return comments.contains(commentId);
}
public Comment getComment(int commentId) {
return comments.get(commentId);
}
public void removeComment(Comment comment) {
comments.remove(comment);
}
}
@Entity
@Table(name="comments")
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public int id;
@ManyToOne
private Entry entry;
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public Entry getEntry() {
return entry;
}
public void setEntry(Entry entry) {
this.entry = entry;
}
}
假设我有一个单页应用程序,它将以下请求发送到后端:
/deleteComment?entryId=5&commentId=7
我的方法是在控制器中通过entryId参数获取Entry。 比我想在Entry-entity上调用containsComment)()方法,我将在其中传递commentId请求参数。 因此,如果集合包含具有给定id或false的注释,我将为true。 如果为true,则将调用getComment()方法来获取Comment实体。 最后,我将简单地使用Comment实体作为参数调用removeComment()方法。
在PHP Doctrine中,我认为这种方法有效。 这也是休眠的正确方法吗?
在示例代码中,如果我调用containsComment()方法,则会收到以下异常:
org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [public int com.mypackage.Comment.id] by reflection for persistent property [com.mypackage.Comment#id] : 7
请注意,我使用EXTRA-LAZY是因为注释可以快速收集大量内容。
您可以通过查询来做到这一点,例如,如果Comment
具有对Entry
的引用,请使用select c from Comment c where c.id = :commentId and c.entry.id = :entryId
如果您获得该注释,则该注释存在您可以立即使用它。
删除评论很容易,只需执行即可。 由于Comment
是关系删除的所有者,因此它也会有效地将其从条目中删除。
忠告一词:HQL / JPQL查询使用关键字id
作为id属性。 在您的情况下,因为id
用@Id
注释是可以的。 但是,如果您还有另一个@Id
字段,则查询的行为将与您期望的不同,因为在查询中使用id
将假设您的意思是@Id
字段。
最后,在comments.contains(commentId)
上做一个comments.contains(commentId)
:像列表这样的Java集合通常会寻找您作为参数传递的元素,但是由于您的集合是List<Comment>
并且您传递了一个id(它是一个int
),因此不应被发现。 我不确定Hibernate集合是否采用了某些特殊的翻译逻辑,但是对于Java程序员来说,调用看起来像是一个错误,因为您从不希望它返回true(就像“苹果列表中是否包含这种橙色?”) 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.