使用IdClass保存含复合主键实体时字段赋值异常求助
问题解决:Field 'signees_email_signee' 无默认值报错
问题背景
已在signees和orders表间建立一对多关联,服务代码中通过se.setEmailSignee("me")给字段赋值,但仍抛出如下错误:
Caused by: java.sql.SQLException: Field 'signees_email_signee' doesn't have a default value
错误原因
OrderEntity关联映射错误:
当前OrderEntity中@MapsId("SigneePK")用法错误,@MapsId需指定复合主键类中的单个属性名,而非整个主键类名。这种错误导致Hibernate无法正确将SigneesEntity的主键值同步到orders表的外键字段。- 复合主键关联未正确映射:
SigneesEntity使用复合主键(receiverType、emailSignee、nuFileDetails),但OrderEntity未明确关联所有主键字段,导致外键字段signees_email_signee无法获取到赋值。
解决方案
1. 修正OrderEntity的关联映射
将OrderEntity中的signee字段映射改为明确关联所有复合主键列:
@Entity(name = "orders") public class OrderEntity implements Serializable { private static final long serialVersionUID = 4981007112274762119L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @ManyToOne @JoinColumn(name="account_id", nullable=true) private AccountEntity account; // 修正后的关联映射 @ManyToOne(cascade = CascadeType.ALL) @JoinColumns({ @JoinColumn(name = "signees_receiver_type", referencedColumnName = "receiverType"), @JoinColumn(name = "signees_email_signee", referencedColumnName = "emailSignee"), @JoinColumn(name = "signees_files_id", referencedColumnName = "files_id") }) private SigneesEntity signee; // 其他属性和方法 }
2. 验证数据库表结构
确保orders表中存在以下三个外键字段:
signees_receiver_typesignees_email_signeesignees_files_id
若字段设置为NOT NULL,需保证Hibernate能通过映射正确赋值。
3. 保持服务层代码逻辑(映射修正后即可生效)
服务层中已正确给SigneesEntity的属性赋值,映射修正后,Hibernate会自动将这些值同步到orders表的对应外键字段:
@Override public OrderDto orderSignature(UserDto user, NuFileDTO nuFileDto) { OrderDto returnVal = new OrderDto(); try { NuFileEntity file = new NuFileEntity(); OrderEntity oe = new OrderEntity(); SigneesEntity se = new SigneesEntity(); file.setFileId(nuFileDto.getFileId()); file.setFileName(nuFileDto.getFileName()); file.setFileType(nuFileDto.getFileType()); file.setFileUploadTimestamp(nuFileDto.getFileUploadTimestamp()); file.setFolder(nuFileDto.getFolder()); file.setLastUpdatedTimestamp(nuFileDto.getLastUpdatedTimestamp()); se.setEmailSignee("me"); se.setReceiverType("signee"); se.setNuFileDetails(file); oe.setSignee(se); oe.setPrice(1000); oe.setRequestTimestamp(Utils.getJakartaCurrentTimestamp()); AccountEntity acc = new AccountEntity(); acc.setId(1); oe.setAccount(acc); orderRepo.save(oe); } catch (Exception e) { e.printStackTrace(); } return returnVal; }
内容的提问来源于stack exchange,提问作者fajar setiawan
相关产品推荐
相关产品推荐

