按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.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);
}

?感谢您的帮助!

解决方法

在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的索引时可能会出现性能问题。

,

我认为问题是您的转换器未初始化User的主键。 您可以根据答案https://stackoverflow.com/a/64141178/14225495来更改id类中User字段的类型,也可以添加注释

@JoinColumn(name = "user_uuid",referencedColumnName = "uuid")

user类中的Book字段。在这种情况下,您还应该在"user_uuid"表中添加列books,确保users.uuid列是唯一的并且不能为空以创建外键。