首页 > 解决方案 > 通过 ID 以外的其他字段映射对象的相关实体

问题描述

我正在使用以下实体:

@Entity
@Table(name = "books")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @ManyToOne
    private User user;
    private UUID uuid = UUID.randomUUID();
}

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String email;
    private String firstName;
    private String lastName;
    private String password;
    @OneToMany(mappedBy = "user")
    private List<Book> books;
    private UUID uuid = UUID.randomUUID();
}

和以下 DTO:

public class NewBookRequest {
    private UUID userUuid;
}

和转换器:

@Component
public class NewBookRequestToEntityConverter implements Converter<NewBookRequest, Book> {

    private final ModelMapper modelMapper;

    public NewBookRequestToEntityConverter(final ModelMapper modelMapper) {
        this.modelMapper = modelMapper;
    }

    @Override
    public Book convert(@NotNull final NewBookRequest source) {
        return modelMapper.map(source, Book.class);
    }
}

并且有部分服务代码:

public void addBook(final NewBookRequest newBookRequest) {
    final Book newBook = newBookRequestToEntityConverter.convert(newBookRequest);
    bookRepository.save(newBook);
}

当我尝试保存转换后的 Book 实体时,我得到了 ConstraintViolationException 异常,因为newBook.user.id它是 null。但是,正确分配了 newBook.user.uuid。有没有办法通过它的 uuid 自动映射 newBook 的用户?或者唯一的解决方案是做这样的事情:

向转换器添加新方法:

@Component
public class NewBookRequestToEntityConverter implements Converter<NewBookRequest, Book> {

    private final ModelMapper modelMapper;

    public NewBookRequestToEntityConverter(final ModelMapper modelMapper) {
        this.modelMapper = modelMapper;
    }

    @Override
    public Book convert(@NotNull final NewBookRequest source) {
        return modelMapper.map(source, Book.class);
    }

    public Book convert(@NotNull final NewBookRequest source, final User user) {
        Book target = modelMapper.map(source, Book.class);
        target.setUser(user);
        return target;
    }
}

并修改服务代码:

public void addBook(final NewBookRequest newBookRequest) {
    final User user = userRepository.getUserByUuid(newBookRequest.getUserUuid());
    final Book newBook = newBookRequestToEntityConverter.convert(newBookRequest, user);
    bookRepository.save(newBook);
}

? 谢谢你的帮助!

标签: javaspringspring-datamodelmapper

解决方案


在 Book 或 User 实体中,您可以使用 UUID 作为主键。你试过吗?

@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
    name = "UUID",
    strategy = "org.hibernate.id.UUIDGenerator",
)
@Column(name = "id", updatable = false, nullable = false)
private UUID id;

但是,在某些数据库上,如果负载很高,则在使用基于 UUID 的索引时可能会出现性能问题。


推荐阅读