JPA 一对一配置,复合主键均为外键

本文详细解释了如何在JPA中正确配置复合主键与一对一关系,避免因错误配置导致的异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里有个比较奇怪的表对应关于

其中一张表的主键为一个复合主键

并且这个复合主键中的字段均对应另一张表的主键

配置如下

主体类:

@Entity
@Table(name="INFO_BRANCH")
public class InfoBranch extends GenericBean implements IDataObject{

	private static final long serialVersionUID = 1918446199175160468L;
	
	@Id
	@Column(name = "branchId", unique=true, nullable = false, columnDefinition = "varchar(10)")
	private String branchId;
	
	@Column(name = "branchName", columnDefinition = "varchar(75)")
	private String branchName;
	
	@Column(name = "creator", columnDefinition = "varchar(10)")
	private String creator;
	
	@Column(name = "createTime",nullable = true)
	@Temporal(TemporalType.TIMESTAMP)
	private Date createTime;
	
	@Column(name = "updater", columnDefinition = "varchar(10)")
	private String updater;
	
	@Column(name = "updateTime",nullable = true)
	@Temporal(TemporalType.TIMESTAMP)
	private Date updateTime;
	
	@Column(name = "deleted", columnDefinition = "varchar(1)")
	private String deleted;

	@OneToOne(mappedBy="infoBranchNew",cascade = CascadeType.ALL)
	private AclBranchTransfer newTransfer;
	
	@OneToOne(mappedBy="infoBranchOld",cascade = CascadeType.ALL)
	private AclBranchTransfer oldTransfer;
}
	


 

客体类,即对应的一那一方:

@Entity
@Table(name="ACL_BRANCH_TRANSFER")
public class AclBranchTransfer extends GenericBean implements IDataObject{

	private static final long serialVersionUID = 1918446199175160469L;
	
	@EmbeddedId
	private AclBeanchTransferId id;
	
	@MapsId("newBranchId")
	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="newBranch",columnDefinition = "varchar(10)")
	private InfoBranch infoBranchNew;
	
	@MapsId("oldBranchId")
	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="oldBranch",columnDefinition = "varchar(10)")
	private InfoBranch infoBranchOld;
	
	@Column(name = "creator", columnDefinition = "varchar(10)")
	private String creator;
	
	@Column(name = "createTime",nullable = true)
	@Temporal(TemporalType.TIMESTAMP)
	private Date createTime;
	
	@Column(name = "updater", columnDefinition = "varchar(10)")
	private String updater;
	
	@Column(name = "updateTime",nullable = true)
	@Temporal(TemporalType.TIMESTAMP)
	private Date updateTime;
	
	@Column(name = "deleted", columnDefinition = "varchar(1)")
	private String deleted;
	


 

其中外键编写如下:

@Embeddable
public class AclBeanchTransferId implements Serializable{
	
	private static final long serialVersionUID = 1918446199175160460L;
	
	private String newBranchId;
	
	private String oldBranchId;

 

主要就是在平常认为的配置方法上加入@mapsId去对应复合主键中的内容

如果按正常情况下的一对一去配置在复合主键中,即newBranchId 和oldBranchId都配置上oneToOne

那么JPA就反应不过来了,为同一张表设两个主键

而我们需要的只是,aclBranchTransfer分别对应两个InfoBranch的信息

所以程序会报:org.hibernate.ejb.metamodel.SingularAttributeImpl$Identifier cannot be cast to javax.persistence.metamodel.ManagedType

google了一下,大概就是复合主键的问题。

所以按我如上的配置就没问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值