使用Java 17.0.2和Spring Bootstrap 3.0.2(与Spring Bootstrap 2.7.x存在相同问题)
(这里有一个示例项目:https://github.com/fistons/issue-spring-data-test)
我有一个实体及其存储库:
@Entity
@Table(name = "customers")
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name", unique = true, nullable = false, length = 255)
private String name;
@Column(name = "region")
@Enumerated(EnumType.STRING)
private Region region;
public enum Region {
US,
EU
}
}
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {}
我创建了一个简单的服务来插入一个新实体
@Service
public class CustomerService {
private final CustomerRepository customerRepository;
public CustomerService(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
@Transactional
public Customer createCustomer(String name, Customer.Region region) {
Customer customer = new Customer();
customer.setName(name);
customer.setRegion(region);
return customerRepository.save(customer);
}
}
我创建了此测试(使用内存H2数据库运行):
@SpringBootTest
@Transactional
class CustomerServiceTest {
@Autowired
private CustomerService customerService;
@Test
public void test_createCustomer() {
Customer createdCustomer = customerService.createCustomer("The Crusher", Customer.Region.EU);
Assertions.assertEquals(4, createdCustomer.getId(), "Id should match");
Assertions.assertEquals("The Crusher", createdCustomer.getName(), "Name should match");
Assertions.assertEquals(Customer.Region.EU, createdCustomer.getRegion(), "Region should match");
}
}
使用此data.sql固定装置:
INSERT INTO customers (id, name, region) VALUES (1, 'Dr. Carmack', 'EU'), (2, 'Pinky', 'EU'), (3, 'Revenant', 'EU');
我在测试应用程序中显式设置了spring.jpa.defer-datasource-initialization: true
。yml
当我运行这个测试时,我遇到了一个异常,我不知道为什么:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["PRIMARY KEY ON PUBLIC.CUSTOMERS(ID) ( /* key:1 */ 1, 'Dr. Carmack', 'EU')"; SQL statement:
insert into customers (id, name, region) values (default, ?, ?) [23505-214]]
当我查看测试日志时,我可以看到hib使用以下请求创建表:
create table customers (
id integer generated by default as identity,
name varchar(255) not null,
region varchar(255),
primary key (id)
)
看起来当服务中有一个插入时,ID应该是4,因为我的fixture中已经有3个插入行。
为什么它试图分配id 1
?我错过了什么吗?
2条答案
按热度按时间fwzugrvs1#
层代类型.标识
此GenerationType指示持久性提供程序必须使用数据库标识列为实体分配主键。IDENTITY列通常用于SQL Server中。此特殊类型列由表本身在内部填充,而不使用单独的序列。如果基础数据库不支持IDENTITY列或某些类似的变量,则持久性提供程序可以选择适当的替代策略。在本例中,我们使用的是不支持IDENTITY列的H2数据库。
您应该考虑将ID持久性类型更改为GenerationType.AUTO或其他类型
suzh9iv82#
Id的生成方式取决于框架和数据库。通常由Sequence完成,而Sequence不知道您的插入,所以它从1开始。您可以注解Customer类,使用哪个序列,并使用此序列在data.sql中创建以避免此错误。