我的 PostgreSQL 数据库中有一个序列,它在插入时为我的订单表生成 order_number(非主键列):
<createSequence
sequenceName="order_number_seq"
startValue="1"
incrementBy="1"
cacheSize="1"/>
<addDefaultValue
tableName="orders"
columnName="order_number"
defaultValueComputed="nextval('order_number_seq')"/>
我的问题是保存订单后,order_number 为空: 科特林
// Save order
order = orderRepository.save(order)
// order.orderNumber is null here
sendEmail(order) // Need order_number here
indexOrder(order) // Need order_number here too
保存后如何检索生成的order_number值?请注意,这不是主键列。
实体:
@Entity
@Table(name = "orders")
class Order(
@Id val id: UUID = UUID.randomUUID(),
@Column(name = "order_number", unique = true, nullable = false, updatable = false, insertable = false)
var orderNumber: Long? = null,
// other fields...
)
在调用发送电子邮件和索引方法之前,我尝试使用
orderRepository.findById(order.id)
获取实体,但仍然不起作用:订单的 orderNumber 仍然为空
order_number 字段已可插入 false
为了在插入上应用默认值,我们需要使用
order_number
:从生成的插入 SQL 中删除
insertable = false
@Entity
@Table(name = "orders")
class Order(
...
@Column(name = "order_number", insertable = false)
var orderNumber: Long? = null,
...
)
因为
order_number
是由数据库填充的,所以您需要在保存后从数据库中获取实体(请参阅下面的测试)。
示例数据库架构 (Postgresql):
CREATE SEQUENCE order_number_seq INCREMENT BY 1 START WITH 1;
CREATE TABLE orders
(
id SERIAL PRIMARY KEY,
order_number INT DEFAULT nextval('order_number_seq') NOT NULL
);
测试
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.testcontainers.containers.PostgreSQLContainer;
import static org.junit.jupiter.api.Assertions.*;
@DataJpaTest
@AutoConfigureTestDatabase
class OrderRepositoryTest {
@TestConfiguration
static class PostgresTestContainerConfig {
@Bean
@ServiceConnection
public PostgreSQLContainer<?> postgreSQLContainer() {
return new PostgreSQLContainer<>("postgres:15-alpine");
}
}
@Autowired
OrderRepository sut;
@Autowired
TestEntityManager entityManager;
@Test
void testSave() {
sut.save(new Order());
entityManager.clear();
var orderInDb = entityManager.find(Order.class, 1L);
assertNotNull(orderInDb.getOrderNumber());
}
}