java - 如果 @GeneratedValue 包含来自另一个实体的外键,则无法使 @GeneratedValue 与 @IdClass 一起使用
问题描述
如果 @GeneratedValue 包含来自另一个实体的外键,我无法让 @GeneratedValue 与 @IdClass 一起使用。
所以我拥有的是一个看起来像这样的选项实体
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "options")
public class Option extends UserDateAudit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "option_id")
private Long optionId;
@NotBlank
@Column(nullable = false)
private String name;
//one to many with optionValues entity
@OneToMany(mappedBy = "option", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
private Set<OptionValue> optionValues;
@OneToMany(mappedBy = "option", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<ProductOption> optionProducts;
}
和一个 OptionValue 实体
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "option_values")
@IdClass(OptionValueId.class)
public class OptionValue extends UserDateAudit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "option_value_id")
private Long optionValueId;
@NotBlank
@Column(nullable = false)
private String valueName;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "option_id", referencedColumnName = "option_id")
private Option option;
@OneToMany(mappedBy = "optionValue", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<VariantValue> variantValues;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OptionValueId implements Serializable {
private Long optionValueId;
private Option option;
}
我试着保存它
public ResponseEntity<OptionValue> create(Long optionId, OptionValueCreateDto optionValueCreateDto) {
Option option = optionRepository.findById(optionId).orElseThrow(
() -> new EntityNotFoundException("errors.option.notFound")
);
OptionValue optionValue = ObjectMapperUtils.map(optionValueCreateDto, OptionValue.class);
optionValue.setOption(option);
optionValue = optionValueRepository.save(optionValue);
return new ResponseEntity<>(optionValue, HttpStatus.CREATED);
}
但我得到以下异常
Resolved [org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.Long' to required type 'com.ecommerce.product.model.Option' for property 'option'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.Long' to required type 'com.ecommerce.product.model.Option' for property 'option': no matching editors or conversion strategy found]
我无法弄清楚这里出了什么问题
我也试着让我的 IdClass 像这样
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OptionValueId implements Serializable {
@Column(name = "option_value_id")
private Long optionValueId;
@Column(name = "option_id")
private Long option;
}
但它效果不佳并显示出类似的异常
编辑 1 事实证明它必须是一个复合键,因为这个复合键与另一个表中的相关使用,这导致了很多问题,以消除复合键提供的验证。
也许我应该首先澄清这一点。
解决方案
该异常与 Spring Data 或 WebMvc 无法转换值有关。将生成的标识符与其他标识符混合是不可能的。为什么你仍然需要这两个值?IMO 在这里有一个复合 id 是没有意义的。只需使用这个:
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "option_values")
@IdClass(OptionValueId.class)
public class OptionValue extends UserDateAudit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "option_value_id")
private Long optionValueId;
@NotBlank
@Column(nullable = false)
private String valueName;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "option_id", referencedColumnName = "option_id")
private Option option;
@OneToMany(mappedBy = "optionValue", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<VariantValue> variantValues;
}
推荐阅读
- python - 无法将 csv 文件导入 jupyter notebook
- node.js - 错误:找不到模块“硒硒”
- angular - 如何查看 Angular 2+ 中的运行错误?
- c# - 如何在 Movilizer 日历屏幕中仅启用月份和年份?
- android - 如何在 Android 上更改阴影高度颜色?
- regex - 用于在引号之间捕获的正则表达式,包括跳过的引号
- c# - 我的 Unity 面板不是我想要的颜色
- javascript - 我想动态导入图像,但我运行项目我没有看到图像
- google-sheets - 我们可以使用谷歌表单脚本验证来自谷歌表单的响应是否存在输入的值?
- java - 单选按钮在 Android 中返回错误的值