gpt4 book ai didi

java - JSR303 验证不验证 @Id 是否不是 @GeneratedValue 与 Spring Data Jpa 和 Hibernate

转载 作者:搜寻专家 更新时间:2023-11-01 01:53:29 25 4
gpt4 key购买 nike

在一个简单的项目中,我喜欢测试 @NotNull 验证(以及其他一些自定义验证)。

因此我写了一些执行此操作的单元测试:@Test(expect=ValidationException.class

重现我上传到 github 上的问题的最小化示例:

我发现如果 @Id 是一个生成的值,它会很好地工作。但是如果@Id是系统给出的,则验证被忽略。

此类将显示重现问题的最小设置:

两个实体(一个有生成值,一个没有:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class GeneratedId {
@Id
@GeneratedValue
private Long id;

@NotNull
private String content;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class GivenId {
@Id
private Long id;

@NotNull
private String content;
}

单元测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:/applicationContext.xml")
@Transactional
@ActiveProfiles("embedded")
public class MyEntityTest
{
@Autowired GeneratedIdService generatedIdService;

@Autowired GivenIdService givenIdService;

// This test will pass
@Test(expected = ValidationException.class)
public void shouldNotAllowNullValues1()
{
this.generatedIdService.save(new GeneratedId());
}

// This test will fail
@Test(expected = ValidationException.class)
public void shouldNotAllowNullValues2()
{
this.givenIdService.save(new GivenId(1L, null));
}
}

这是样板服务和存储库

public interface GeneratedIdRepository extends JpaRepository<GeneratedId, Long> {
}

public interface GivenIdRepository extends JpaRepository<GivenId, Long> {
}

@Service
public class GeneratedIdService {
@Autowired GeneratedIdRepository repository;

public GeneratedId save(final GeneratedId entity) {
return this.repository.save(entity);
}
}

@Service
public class GivenIdService {
@Autowired GivenIdRepository repository;

public GivenId save(final GivenId entity) {
return this.repository.save(entity);
}
}

目前我正在使用 Spring 3.1.4、Spring-Data 1.3.4、Hibernate 4.1.10 和 Hibernate-Validator 4.2.0。

关于跳过验证的任何建议?

编辑 1:

我在两个实体上都没有使用 lombok 进行了尝试,仍然出现错误。

最佳答案

如果您想强制持久性提供程序刷新 EntityManager 事务提交或回滚之前,您需要手动刷新它或使用 saveAndFlush( …)JpaRepository 上。

原因是在自动生成 ID 的情况下,持久性提供程序必须刷新才能将 ID 绑定(bind)到 Java 对象。在手动分配 ID 的情况下,根本不需要在比事务结束时更早的时间点刷新,因此持久性提供程序避免了数据库交互。

除了这些技术细节之外,我认为依赖持久性提供程序进行这种验证无论如何在架构上都是有问题的。如果提供者检测到违规,您实际上已经通过各种业务逻辑传输了一个无效对象。为了确保您不必进行防御性编码(对每个地方进行 null 检查),您可以通过检查传递给构造函数或 setter 的值来简单地强制该属性不可为空。通过这种方式,您基本上知道无论何时获取对象的实例,该值都永远不会是null,无论是否调用了某个第三方框架,或者某些开发人员不小心忘记调用它。

关于java - JSR303 验证不验证 @Id 是否不是 @GeneratedValue 与 Spring Data Jpa 和 Hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18278776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com