首页 > 解决方案 > 保存到 CRUDRepository 时如何防止 Spring JPA 实体变为可选?

问题描述

我正在尝试学习 Spring Framework,但在将实体保存到 CRUD 存储库时遇到了问题。我有几个具有自动数字 ID 生成功能的实体,它们工作得很好,但后来我尝试创建一个以 String 作为主键的类,如下所示:

@Entity
@Table(name = "USERS")
@Builder
public class User {
    @Id
    @Column(name = "USER_NAME", nullable = false)
    @Getter @Setter
    private String name;

    @Column(name = "USER_PASS", nullable = false)
    @Getter @Setter
    private String pass;
}

首先,我得到关于这个类没有默认构造函数的异常:

org.springframework.orm.jpa.JpaSystemException: No default constructor for entity:  : com.company.Model.User; nested exception is org.hibernate.InstantiationException: No default constructor for entity:  : com.company.Model.User

已经很奇怪了,但我还是决定将 @Builder 注释更改为 2 个构造函数,一个带有两个参数,第二个没有。我尝试通过典型测试将实体实例保存到 CRUD Repository userDAO(无非是扩展 CRUDRepository 的接口)中:

User admin = new User("admin", "6aDcZ72k");

...

@Test
public void saveUserAndFindById() {
    admin = userDAO.save(admin);
    assertThat(userDAO.findById(admin.getName())).isEqualTo(admin);
}

结果是断言失败,因为保存的实体具有“可选”类型:

org.junit.ComparisonFailure: 
Expected :com.company.Model.User@2c06b113
Actual   :Optional[com.company.Model.User@2c06b113]

我知道我做错了什么,但无法弄清楚。或者也许有一种方法可以防止它成为可选的?这个类的引用肯定很少有其他实体,但由于上述问题,这些引用显然不起作用。

标签: javaspringspring-data-jpa

解决方案


save(...)回来的不是你,Optional而是userDAO.findById(admin.getName()。根据文档,CrudReposiotry提供了一个findById()返回类型为Optional<T>.

public interface CrudRepository<T, ID extends Serializable>
  extends Repository<T, ID> {
    Optional<T> findById(ID primaryKey);
}

如果您不想Optional作为返回类型,则需要提供自己的方法来执行此操作。例如:

public interface PeronRepository extends CrudRepository<Person, String> {
    Person findById(String personId);
}

推荐阅读