不确定为与@JoinTable具有多个@OneToMany关联的实体实现CrudRepository的最佳方法
@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<>();
public interface ContactRepo extends CrudRepository<Contact, Long> {
List<Contact> findByLastNameContainingIgnoreCase(String lastName);
}
我有FetchType.LAZY,所以我不能从2个笛卡尔乘积得到MultipleBagFetchException。因此,我知道我需要将两个连接分开,这就是我被困在最佳解决方案的地方。放入一个自定义的存储库和customImpl类,它可以访问EntityManager并编写出2个连接?我没有发疯,让Java通过一个集合来处理笛卡尔,也没有让FetchType.EAGER处理另一个查询??
生成:
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返回电话号码和电子邮件地址。
但是,服务不需要。
@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());
}
}
[
{
"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": []
}
]
发布于 2021-01-12 20:40:03
DataJpaTest与手动集成测试的不同之处在于,我决定看一看地图,确保我没有走错谷歌路线。我打开了H2控制台,发现即使发生了插入,连接表也是空的。然而,我注意到我在实时测试和自动化测试中得到了不同的连接表列名。
解决方案是显式地命名连接表列。看起来Spring已经在一个实体中处理了多个OneToMany JoinTable属性的MultipleBagFetchException问题。
@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<>();
https://stackoverflow.com/questions/65677948
复制相似问题