【发布时间】:2020-10-24 09:43:49
【问题描述】:
我有一个名为 Franchise 的实体,这个实体看起来像这样:
@Data
@Entity
@Table(name = "franchises")
public class Franchise {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Enumerated(EnumType.STRING)
private FranchiseType type;
@ToString.Exclude
@EqualsAndHashCode.Exclude
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "country_id")
private Country country;
}
我有以下用于创建新特许经营实体的 api 端点:POST /api/franchise
我需要发送的字段是:name、type 和 countryId。 countryId 是可选字段,在数据库中可以为空(country_id 列)。
我正在使用 mapstruct 将 CreateFranchiseDTO 映射到 Franchise:
@Data
public class CreateFranchiseDTO {
private String name;
private String type;
private Long countryId;
}
@Mapper(componentModel = "spring")
public interface FranchiseDTOMapper {
@Mapping(source = "countryId", target = "country.id")
Franchise fromCreateFranchiseDTO(CreateFranchiseDTO dto);
}
当我调用上述 api 端点并将countryId 设置为某个整数(存在于countries 表中)时,一切正常。但是,如果我在请求正文中调用没有countryId 字段的端点并且当执行以下代码时,我会得到异常object references an unsaved transient instance:
Franchise franchise = franchiseDTOMapper.fromCreateFranchiseDTO(dto);
franchiseRepository.save(franchise);
当我查看调试器时,我可以看到 franchise.getCountry() 等于 Country 对象,所有字段都设置为 NULL 或零/false(原语的默认值)
我有几个选项可以解决这个问题:
- 使用
@AfterMapping并检查franchise.getCountry().getId() == null - 在映射器中创建以下方法:
Country longToCountry(Long id)
但在我看来,我错过了什么或者我错了。那么如何使用 mapstruct 将可选 ID(关系)映射到字段?
【问题讨论】:
标签: java spring hibernate jpa mapstruct