使用JPA处理庞大的一对多集合的最佳方式

时间:2014-03-12 07:38:00

标签: java jpa one-to-many objectdb

假设我们有一个实体“Something”,这个东西与某些“数据”有一对多(数百万)的关系。

Something 1 -> * Data
Data 1 -> 1 Something

现在,如果我们想要添加一些数据对象,我们应该这样做:

Something.getDataList().add(Data)

这实际上会从数据库中提取所有数据对象,这不是最佳的。

但是,如果我从Something中删除关系,并将其保留在Data中,我将能够添加和检索我要求使用DAO的那些对象:

Something
Data 1 -> 1 Something

现在数据访问界面将如下所示:

Something.addData(Data) // will use DataDAO to save object

Something.addData(List<Data>) // will use same DataDAO batch insert

我需要一些指导,也许我对JPA缺乏一些知识,而且没有必要这样做?另外我不确定实体是不是很自然,因为数据是由他们的方法提供的,但实际上并没有包含在实体中(如果这是正确的话,那么如果存在性能关键操作,我应该删除每一对多的关系与那个特殊的实体,这也是不自然的。)

在我的特定情况下,我有很多REST消费者会定期更新数据库。我正在使用ObjectDB,JPA ......但问题在这里更抽象。

1 个答案:

答案 0 :(得分:2)

如果有something.getDataList()个与Data相关的Something条记录,我认为让something.getDataList().add(data)左右是点击炸弹。正如您所说,调用something.getDataList().size将从DB获取整个数据集以执行单个插入。此外,任何人都可能想要使用void addData(Something something, Data data){ //Something similar can be used for batch insert data.setSomething(something); em.persist(data); } List<Data> findData(Something something, MyFilter filter){ // use a NamedQuery with parameters populated by something and your filters return em.getResultList(); } Long countData(Something something){ // use a 'SELECT COUNT(*) FROM Data d WHERE d.something = :something' NamedQuery return em.getSingleResult; } 来获取记录数量,从而产生相同的开销。

我的建议是您使用DataDAO进行此类操作(即添加或计数),如:

{{1}}