首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring Boot2,Spring5JPA:处理多个OneToMany JoinTables

Spring Boot2,Spring5JPA:处理多个OneToMany JoinTables
EN

Stack Overflow用户
提问于 2021-01-12 12:12:39
回答 1查看 38关注 0票数 0

不确定为与@JoinTable具有多个@OneToMany关联的实体实现CrudRepository的最佳方法

代码语言:javascript
运行
复制
@Entity
@Table(name = "contact", uniqueConstraints = {@UniqueConstraint(columnNames ={"first_name","last_name"})})
@SuppressWarnings("PersistenceUnitPresent")
public class Contact extends Auditable implements Serializable {

    @Id
    @Column(name = "contact_id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "contact_generator")
    @SequenceGenerator(name = "contact_generator", sequenceName = "contact_seq", allocationSize = 50)
    private Long contactId;

    @Column(name = "first_name", nullable = false)
    private String firstName;
    
    @Column(name = "last_name", nullable = false)
    private String lastName;
    
    @Column(name = "middle_name", nullable = true)
    private String middleName;
    
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    @JoinTable( 
        name = "contact_phone"
    )
    private List<Phone> phoneNumbers = new ArrayList<>();
    
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    @JoinTable(name = "contact_email")
    private List<EmailAddress> emailAddresses = new ArrayList<>();
代码语言:javascript
运行
复制
public interface ContactRepo  extends CrudRepository<Contact, Long> {
    
    List<Contact> findByLastNameContainingIgnoreCase(String lastName);

}

我有FetchType.LAZY,所以我不能从2个笛卡尔乘积得到MultipleBagFetchException。因此,我知道我需要将两个连接分开,这就是我被困在最佳解决方案的地方。放入一个自定义的存储库和customImpl类,它可以访问EntityManager并编写出2个连接?我没有发疯,让Java通过一个集合来处理笛卡尔,也没有让FetchType.EAGER处理另一个查询??

生成:

代码语言:javascript
运行
复制
    create table contact (
       contact_id bigint not null,
        create_tm timestamp not null,
        created_by varchar(255) not null,
        updated_tm timestamp not null,
        updated_by varchar(255) not null,
        first_name varchar(255) not null,
        last_name varchar(255) not null,
        middle_name varchar(255),
        primary key (contact_id)
    )
    create table email_address (
       email_id bigint not null,
        email_addr varchar(255) not null,
        email_type varchar(255),
        primary_addr boolean default false,
        primary key (email_id)
    )

    create table contact_email (
       Contact_contact_id bigint not null,
        emailAddresses_email_id bigint not null
    )

    create table phone (
       phone_id bigint not null,
        phone_nbr varchar(255) not null,
        phone_type varchar(255),
        primary_ph boolean default false,
        primary key (phone_id)
    )

    create table contact_phone (
       Contact_contact_id bigint not null,
        phoneNumbers_phone_id bigint not null
    )

奇怪的是我的JpaDataTests worked。find all和findByLastNameContainingIgnoreCase返回电话号码和电子邮件地址。

但是,服务不需要。

代码语言:javascript
运行
复制
    @Autowired
    private ContactRepo contactRepo;
    
    @Override
    public List<Contact> findAllContacts() throws GcaServiceException {
        try {
            Iterable<Contact> iter = contactRepo.findAll();
            return IteratorUtils.toList(iter.iterator());
        } catch(DataAccessException e) {
            throw new GcaServiceException(e.getMessage());
        }
    }
    
    @Override
    public List<Contact> findByLastName(String lastName) throws GcaServiceException {
        try {
            return contactRepo.findByLastNameContainingIgnoreCase(lastName);
        } catch (DataAccessException e) {
            throw new GcaServiceException(e.getMessage());
        }
    }
代码语言:javascript
运行
复制
[
      {
      "createTm": "2021-01-11T16:27:19.995011",
      "createdBy": "UncleMoose",
      "updatedBy": "UncleMoose",
      "updateTm": "2021-01-11T16:27:19.995011",
      "contactId": 1,
      "firstName": "Bruce",
      "lastName": "Randall",
      "middleName": null,
      "phoneNumbers": [],
      "emailAddresses": []
   },
      {
      "createTm": "2021-01-11T16:27:19.996009",
      "createdBy": "UncleMoose",
      "updatedBy": "UncleMoose",
      "updateTm": "2021-01-11T16:27:19.996009",
      "contactId": 51,
      "firstName": "Boss",
      "lastName": "Randall",
      "middleName": null,
      "phoneNumbers": [],
      "emailAddresses": []
   }
]
EN

回答 1

Stack Overflow用户

发布于 2021-01-12 20:40:03

DataJpaTest与手动集成测试的不同之处在于,我决定看一看地图,确保我没有走错谷歌路线。我打开了H2控制台,发现即使发生了插入,连接表也是空的。然而,我注意到我在实时测试和自动化测试中得到了不同的连接表列名。

解决方案是显式地命名连接表列。看起来Spring已经在一个实体中处理了多个OneToMany JoinTable属性的MultipleBagFetchException问题。

代码语言:javascript
运行
复制
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    @JoinTable( 
        name = "contact_phone"
       ,joinColumns = @JoinColumn(name = "contact_id")
       ,inverseJoinColumns = @JoinColumn(name = "phone_id")
    )
    private List<Phone> phoneNumbers = new ArrayList<>();
    
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    @JoinTable(
        name = "contact_email"
       ,joinColumns = @JoinColumn(name = "contact_id")
       ,inverseJoinColumns = @JoinColumn(name = "email_id")
    )
    private List<EmailAddress> emailAddresses = new ArrayList<>();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65677948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档