优化 Spring-data / Hibernate ManyToMany 插入

Posted

技术标签:

【中文标题】优化 Spring-data / Hibernate ManyToMany 插入【英文标题】:Optimizing Spring-data / Hibernate ManyToMany Inserts 【发布时间】:2013-09-26 17:13:38 【问题描述】:

我对 Hibernate 处理插入 JoinTable 的方式有点困惑。

我需要在 JoinTable 中添加一些额外的字段,所以我选择了一种非常常见的方式,为 JoinTable 创建一个@Entity 并使用@OneToMany@ManyToOne。因为关系应该是唯一的,所以我在 JoinTable-Entity 中创建了一个@EmbeddedId

让我们调用 ABAB 类:

@Entity
public class A implements Serializable 
    @OneToMany(mappedBy="a", cascade=CascadeType.ALL, orphanRemoval=true)
    private Set<AB> abs;        


@Entity
public class B implements Serializable 
    @OneToMany(mappedBy="b", cascade=CascadeType.ALL, orphanRemoval=true)
    private Set<AB> abs;        


@Entity
public class AB implements Serializable 
    @Embeddable
    public static class Id implements Serializable 
        UUID aId;
        UUID bId;

        public Id(UUID aId, UUID bId) 
            this.aId = aId;
            this.bId = bId;
        
    

    public AB(A a, B b) 
        this.id.aId = a.getId();
        this.id.bId = b.getId();
        this.a = a;
        this.b = b;
    

    @EmbeddedId
    private Id id;      

    @MapsId("aId")
    @ManyToOne
    @JoinColumn(nullable=false, updatable=false)
    private A a;

    @MapsId("bId")
    @ManyToOne
    @JoinColumn(nullable=false, updatable=false)
    private B b;        

我的常见情况是,我想在 JoinTable 中插入多个新条目。所以我有一个A_id 和多个B_ids。在纯 SQL 中,我只需执行一次查询即可完成所有操作。如果关系已经存在,数据库将抛出错误。

使用休眠我需要:

    SELECT:给我一个 A 类的实例,因为 id = A_id SELECT:给我一个 B 类的实例,用于 id = B_id1 或 id = B_id2 或 ... 创建类AB的新实例并设置复合主键并保存AB

最后一步产生(对于每个AB):

    从 AB 中选择 *,其中 a_id = ... 和 b_id = ... 插入 AB (aId, bId) 值 (..., ...)

这是我的代码。使用spring数据jpa(JpaRepository):

A a = aRepo.findOne(aId);
List<B> bs = bRepo.findAll(bIdList);
for(B b : bs) 
    AB ab = new AB(a, b);
    abRepo.save(ab);

groupUserRepo.flush();

如果我只是用 AB 对象创建一个新的 ArrayList,然后一次保存所有这些对象,或者像上面的代码中那样做,这并不重要。它总是对每个对象进行选择和插入。

有没有办法用更少的查询来做到这一点?

【问题讨论】:

***.com/questions/5127129/… 有一些有用的信息。 Hibernate 必须执行的那些额外查询没有任何意义 【参考方案1】:

这很奇怪,因为您看到的是 saveOrUpdate 对分离对象的行为。 我希望 hibernate 为AB 发出选择,如果它们是分离的对象,而不是AB,因为你正在调用save

你可以试试persist 看看它是否改变了什么。

【讨论】:

感谢您的回答。问题是:我使用的是 spring-data-jpa,它不提供持久或合并等方法。它只有savesaveAndFlush 尝试实现 Persistable。见docs.spring.io/spring-data/jpa/docs/1.4.1.RELEASE/reference/…

以上是关于优化 Spring-data / Hibernate ManyToMany 插入的主要内容,如果未能解决你的问题,请参考以下文章

在 spring-data 项目中使用 @Version

Hibernat 原生SQL运行结果集处理方法

Spring-data:阻止更新

通过 spring-data 迭代 MongoDB 中的大型集合

spring-data 存储库自定义查询

使用 Spring-Data 配置 MongoDb 时出现异常