【发布时间】:2021-04-17 01:12:23
【问题描述】:
不确定为具有多个实体的实体实施 CrudRepository 的最佳方法 @OneToMany 与 @JoinTable 的关联
@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。 所以我知道我需要将 2 个连接分开,这是我坚持最佳解决方案的地方。 放入可以访问 EntityManager 并编写 2 个连接的自定义 repo 和 customImpl 类? 我不是疯了,让 Java 通过 Set 来处理笛卡尔,也不是拥有 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 工作发现。 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": []
}
]
【问题讨论】:
标签: spring spring-boot jpa spring-data-jpa