gpt4 book ai didi

java - 运行 spring boot JPA 测试时数据库中没有任何值

转载 作者:行者123 更新时间:2023-11-29 08:21:44 25 4
gpt4 key购买 nike

我正在查看 spring-data-jpa 中映射列默认值的解决方案,这使我找到了 @ColumnDefault 注释的文档;我想尝试一下。所以我更新了一个我们需要默认值的实体(今天这是通过我们定义额外列行为的 schema.sql 处理的),如下所示:

@Entity
@Getter
@Setter
@ToString
@DynamicInsert
@NoArgsConstructor
@Relation(collectionRelation = "customers")
public class Customer extends Organisation implements Identifiable<Long>, Serializable {

private static final long serialVersionUID = 8101819808147191270L;

@Column(nullable = false, updatable = false, length = 3)
@ColumnDefault("'INR'")
private String currency;

@Column(scale = 2)
@ColumnDefault("0.10")
private Double tds;

@Column(nullable = false, updatable = false, length = 3)
@ColumnDefault("'INV'")
private String invoicePrefix;

现在,由于我使用的是 @ColumnDefault,因此我希望为列配置默认值,当我查看数据库时它们就是这样。但是,当我运行测试以插入值时;默认字段为 null。我为测试配置了 Postgresql(因为生产将在 Postgresql 中);虽然 Postgresql 中表的 DDL 显示默认值已添加到表定义

CREATE TABLE data_api_it.customer
(
currency character varying(3) COLLATE pg_catalog."default" NOT NULL DEFAULT 'INR'::character varying,
invoice_prefix character varying(3) COLLATE pg_catalog."default" NOT NULL DEFAULT 'INV'::character varying,
tds double precision DEFAULT 0.10,
id bigint NOT NULL,
CONSTRAINT customer_pkey PRIMARY KEY (id),
CONSTRAINT fk3afgab8nfy6ykn6b70uuh9v59 FOREIGN KEY (id)
REFERENCES data_api.organisation (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)

这是失败的测试

@Slf4j
@RunWith(SpringRunner.class)
@DataJpaTest(showSql = false)
@ContextConfiguration(classes = { DataApiJpaConfiguration.class })
@TestPropertySource(locations = {"classpath:application-it.properties","classpath:application-test.properties"})
@AutoConfigureTestDatabase(replace = Replace.NONE)
public class CustomerRepositoryIntegrationTest {

@Autowired
private CustomerRepository customerRepository;

@Test
public void testPrePersistAddsMandatoryFields() {

Customer bhau = new Customer();
bhau.setName("Bhau & Sons Pvt. Ltd.");
bhau.setDomain(RandomStringUtils.randomAlphanumeric(8));
bhau = customerRepository.saveAndFlush(bhau);
Customer badaBhau = customerRepository.findById(bhau.getId()).get();
assertThat(badaBhau.getTds().doubleValue()).isEqualTo(0.10);
assertThat(badaBhau.getInvoicePrefix()).isEqualTo("INV");
assertThat(badaBhau.getCurrency()).isEqualTo("INR");
}

}

失败是 assertThat(badaBhau.getTds().doubleValue()).isEqualTo(0.10); 处的 NullPointerException 当我运行调试时,我注意到 badaBhau 在从数据库查询时确实没有设置默认值。然后当它仍然存在时,我在该行之后暂停了 bhau;浏览配置的测试数据库并注意到 bhau 实体甚至没有首先保存到数据库中。

我还使用 Postgesql Dev DB 运行该应用程序,尝试访问 API url 以使用 JSON 数据保存客户

{
"name":"Minty and Sons Pvt. Ltd.",
"pan": "AASONAL123",
"domain": "xy123456"
}

此调用成功创建了类(class)记录,默认值为 INRINV0.10 for currency , invoice_prefixtds

因此,虽然我了解并喜欢 @ColumnDefault 为我解决了默认值问题;我对测试失败的原因(或者我做错了什么)感到非常困惑

最佳答案

由于Hibernate的一级缓存,bhaubadaBhau会是同一个实例,即。不会有由以下内容触发的数据库查找:而是从一级缓存中检索具有指定 ID 的客户。您可以通过启用 SQL 日志记录来验证这一点。

客户 badaBhau = customerRepository.findById(bhau.getId());//没有数据库查找

要获得该值,可以通过清除持久性上下文或刷新持久性实例来强制进行数据库查找。

public class MyTestClass {

@PersistenceContext
private EntityManager em;

@Test
public void testDefaultFieldsArePopulated() {

Customer bhau = new Customer();
bhau.setName("Bhau & Sons Pvt. Ltd.");
bhau.setDomain(RandomStringUtils.randomAlphanumeric(8));

bhau = customerRepository.saveAndFlush(bhau);
em.clear(); //db lookup will now happen

Customer badaBhau = customerRepository.findById(bhau.getId());
assertThat(badaBhau.getTds().doubleValue()).isEqualTo(0.10);
assertThat(badaBhau.getInvoicePrefix()).isEqualTo("INV");
assertThat(badaBhau.getCurrency()).isEqualTo("INR");
}
}

https://howtodoinjava.com/hibernate/understanding-hibernate-first-level-cache-with-example/

Crizzis 在他的回答中也提出了一个有效的观点,随着测试的通过,看起来 Postgres 正在用列的默认值替换空值。由于您可能无法跨不同的数据库引擎依赖于此,因此您还可以考虑在您的实体上使用 Hibernates @DynamicInsert 注释,这将创建一个仅设置非空字段的插入语句。

https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/annotations/DynamicInsert.html

For inserting, should this entity use dynamic sql generation where only non-null columns get referenced in the prepared sql statement?

关于java - 运行 spring boot JPA 测试时数据库中没有任何值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57175477/

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