[英]Any way to do one-to-many association by non primary key in JPA-hibernate
我正在尝试通过父项的非主键进行一对多关联。 我在休眠中使用 JPA 2.1。 我发现了几个类似的问题。 但我认为我的情况有点不同。
我有两个表: 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`);
我有其他表,并从这些表中创建了几个views
,在某些情况下profile_id
是这些视图的Primary Key
。 我已经成功地从views
完成one to many
关联,其中主键是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]
是错误的值: view
PK ,其中正确的值将是1134
。 但正如我之前所说,这是在视图的主键是profile_id
。
我在stackoverflow
看到了几个问题。 现在我想知道:有什么方法可以通过one-to-many
关联phone number
,其中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
}
连接列不需要是主键的一部分,或者在两个表中使用相同的列名。 您可以使用“referenceColumnName”指定要加入的列。
@Entity
public class ProfileBasic
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "profile_id")
private Long id;
//....some columns.
@OneToMany(cascade = CascadeType.ALL, mappedBy = "profile", orphanRemoval = true)
private List<PhoneNumber> phone_number;
// getters-setters
}
public class PhoneNumber implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "profile_id")
@JoinColumn(name = "profile_id", referencedColumnName = "profile_id", nullable = false)
private ProfileBasic profile;
// getters-setters
}
您应该以这种方式更正您的映射:
@Entity
public class ProfileBasic {
//....some columns.
@OneToMany(cascade = CascadeType.ALL, mappedBy = "profile", orphanRemoval = true)
private List<PhoneNumber> phoneNumbers;
}
@Entity
public class PhoneNumber implements Serializable {
// getters-setters and other columns
@ManyToOne
@JoinColumn(name = "profile_id", nullable = false)
private ProfileBasic profile;
}
注释:
@JoinColumn
注释应该用在拥有外键列的一侧(在您的情况下是PhoneNumber
)。
当 FK referencedColumnName
PK 列时,不必使用referencedColumnName
。
最好遵循java 命名约定。 因此,最好使用phoneNumbers
作为属性名称而不是phone_number
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.