查询存储在单独集合中的@Embeddable对象

Mil*_*nov 5 hibernate jpa spring-data spring-data-jpa

我有一个简单的关系,其中实体具有许多特定于它的地址,定义为:

@Entity
public class Corporation {

    @Id
    private Long id;

    @ElementCollection
    @CollectionTable(name = "addresses_table", joinColumns = @JoinColumn(name = "corporation_id"))
    private List<Address> addresses = new ArrayList<>();
}
Run Code Online (Sandbox Code Playgroud)

Address类都被注解@Embeddable。这非常有用,因为公司的每次更新都会删除其所有地址,然后插入新地址。这正是我要寻找的行为。我试过其他选项(OneToManyManyToMany)因为我需要赴汤蹈火,但仍没有得到简单的全部删除+插入所有的行为导致较差的性能。

但是,有一个简单的要求,即我需要能够按某些条件查询地址。基本上,这可以归结为一种简单的findAll(Pageable pageable, Specification spec)方法。这对于当前和将来的用例就足够了。

现在问题来了,可嵌入对象不是Entitys,因此我无法为其创建Spring数据存储库。我能想到的唯一选择是:

  1. 使用本机实体管理器实现自定义存储库,但是我不确定如何在代码方面以及它是否可以支持泛型方面做到最佳Specification。如果不能,我仍然可以忍受,因为将在其上搜索地址的字段不会改变。
  2. 进行一些联接查询select sth from Corporation c join c.addresses,然后根据地址属性限制结果。在这里我再次不确定这是否行得通,并且像直接对地址表进行简单排队一样表现出色

无论是关于所描述的选项还是用于其他替代方案,任何建议都将受到赞赏。

Ken*_*han 2

单个表可以映射到不同的类。那么为什么不创建另一个Address常用类@Entity,以便您可以为其创建存储库并使用Specification您想要使用的类。

可以@Embeddable Address被视为Corporation提供删除所有+插入所有行为的内部类。如果你希望域客户端只处理一Address类,你可以简单地在@EmbeddableAddress和@EntityAddress之间进行转换。

就代码而言,它看起来像:

@Entity
public class Corporation {

    @Id
    private Long id;

    @ElementCollection
    @CollectionTable(name = "addresses_table", joinColumns = @JoinColumn(name = "corporation_id"))
    private List<CorporationAddress> addresses = new ArrayList<>();


    public void addAddress(Address address){
       addresses.add(new CorporationAddress(address));
    }

    public List<Address> getAddresses(){
       return addresses.stream()
            .map(CorporationAddress::toAddress).collect(toList());
    }

}


//Or you can put it as the internal static nested class inside Corporation if you like
@Embeddable
public class CorporationAddress {

    //Create from Address
    public CorporationAddress(Address){
    }

    //Convert to Address
    public Address toAddress(){

    }

}

@Entity
public class Address {


} 
Run Code Online (Sandbox Code Playgroud)