我正在尝试通过父级的非主键进行一对多关联。我正在使用jpa2.1和hibernate。我发现了几个类似的问题。但我觉得我的情况有点不同。
我有两张table: ProfileBasic
以及 Phonenumber
.
@Entity
public class ProfileBasic {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "profile_id")
private Long id;
//....some columns.
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "profile_id")
private List<PhoneNumber> phone_number;
// getters-setters
}
public class PhoneNumber implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
// getters-setters and other columns
}
数据库表:
CREATE TABLE `profilebasic` (
`profile_id` bigint(20) NOT NULL,
`available` varchar(255) DEFAULT NULL,
`birth_date` varchar(255) DEFAULT NULL,
`blood_Group` varchar(255) DEFAULT NULL,
`care_of` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`gender` varchar(255) DEFAULT NULL,
`marital_status` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`profession` varchar(255) DEFAULT NULL,
`religion` varchar(255) DEFAULT NULL,
`user_id` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Indexes for table `profilebasic`
--
ALTER TABLE `profilebasic`
ADD PRIMARY KEY (`profile_id`);
CREATE TABLE `phonenumber` (
`id` bigint(20) NOT NULL,
`number` varchar(255) DEFAULT NULL,
`profile_id` bigint(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Indexes for table `phonenumber`
--
ALTER TABLE `phonenumber`
ADD PRIMARY KEY (`id`),
ADD KEY `FK8sfxu3ejjpklkd3njt3767ape` (`profile_id`);
--
-- Constraints for table `phonenumber`
--
ALTER TABLE `phonenumber`
ADD CONSTRAINT `FK8sfxu3ejjpklkd3njt3767ape` FOREIGN KEY (`profile_id`) REFERENCES `profilebasic` (`profile_id`);
我还有别的table,做了好几张 views
从那些table上,有些箱子 profile_id
是 Primary Key
在那些观点上。我做得很成功 one to many
来自的关联 views
,其中主键是 profile_id
. 但我有一个观点,在哪里 profile_id
不是pk,因此在取数时,它生成的查询是正确的,但值是错误的。
Hibernate: select phone_numb0_.profile_id as profile_3_18_0_, phone_numb0_.id as id1_18_0_, phone_numb0_.id as id1_18_1_, phone_numb0_.number as number2_18_1_ from PhoneNumber phone_numb0_ where phone_numb0_.profile_id=?
2020-08-23 04:00:48.396 TRACE 9292 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [21451]
在这里 parameter [1] as [BIGINT] - [21451]
是错误的值:pk的 view
,其中正确的值为 1134
. 但正如我之前所说的,这在视图的主键所在的位置起作用 profile_id
.
我在书中看到几个问题 stackoverflow
. 现在我想知道:有没有什么方法可以让我把 phone number
由 one-to-many
,在哪里 profile_id
不是pk。如果不可能的话,我就得看每一行的电话号码 views
.
查看实体:
@Entity
@Table(name = "donner_assing_show")
public class DonnerAssingShow implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "donner_assingment_id")
private long donnerAssingmentId;
@Size(max = 255)
@Column(name = "agent_id")
private String agentId;
@Size(max = 255)
@Column(name = "donner_id")
private String donnerId;
@Size(max = 255)
@Column(name = "assing_date")
private String assingDate;
@Lob
@Size(max = 2147483647)
@Column(name = "assing_note")
private String assingNote;
@Size(max = 255)
@Column(name = "need_date")
private String needDate;
@Size(max = 255)
@Column(name = "post_id")
private String postId;
@Size(max = 255)
@Column(name = "blood_manage_status")
private String bloodManageStatus;
@Basic(optional = false)
@NotNull
@Column(name = "profile_id")
private long profileId;
@Size(max = 255)
@Column(name = "available")
private String available;
@Size(max = 255)
@Column(name = "birth_date")
private String birthDate;
@Size(max = 255)
@Column(name = "blood_Group")
private String bloodGroup;
@Size(max = 255)
@Column(name = "care_of")
private String careOf;
// @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
@Size(max = 255)
@Column(name = "email")
private String email;
@Size(max = 255)
@Column(name = "gender")
private String gender;
@Size(max = 255)
@Column(name = "marital_status")
private String maritalStatus;
@Size(max = 255)
@Column(name = "name")
private String name;
@Size(max = 255)
@Column(name = "profession")
private String profession;
@Size(max = 255)
@Column(name = "religion")
private String religion;
@Size(max = 255)
@Column(name = "user_id")
private String userId;
@OneToMany
// @OneToMany(fetch = FetchType.EAGER)
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name = "profile_id")
private List<PhoneNumber> phone_number;
// @OneToMany
@OneToMany(fetch = FetchType.EAGER)
// @LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name = "profile_id")
private List<Address> addressList;
// constructor-getter/setters
}
项目的github链接
代码的单元测试
项目转储数据
2条答案
按热度按时间baubqpgj1#
联接列不必是主键的一部分,也不必在两个表中使用相同的列名。可以使用“referencecolumnname”指定要加入的列。
vx6bjr1n2#
应按以下方式更正Map:
评论:
这个
@JoinColumn
注解应该用在拥有外键列的一侧(这是PhoneNumber
在你的情况下)。没有必要使用
referencedColumnName
当fk裁判到pk栏时。遵循java命名约定是很好的。所以,最好使用
phoneNumbers
作为属性名而不是phone_number
.