0

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

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

让我们调用类AB并且AB

@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 中,我只需执行一次查询即可完成所有操作。如果关系已经存在,数据库将抛出错误。

使用休眠我需要:

  1. SELECTA: 给我一个id =的类实例A_id
  2. SELECTB: 给我一个id = B_id1or id = B_id2or ...的类实例
  3. 创建类的新实例AB并设置复合主键并保存AB

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

  1. select * from AB where a_id = ... and b_id = ...
  2. 插入 AB (aId, bId) 值 (..., ...)

这是我的代码。使用弹簧数据 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 然后一次保存所有这些对象,或者像上面的代码中那样做,这并不重要。它总是对每个对象进行选择和插入。

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

4

1 回答 1

0

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

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

于 2013-09-27T02:14:22.493 回答