这是一个MRE:
package com.example.h2_demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.jdbc.Sql;
import java.util.List;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@DataJpaTest
@ActiveProfiles("test")
@Sql(
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
scripts = {"/create_user_table.sql", "/insert_user.sql"}
)
public class H2DemoApplicationTest {
private final UserRepository userRepository;
@Autowired
public H2DemoApplicationTest(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Test
void testNothing() {
}
@Test
void getUsers() {
List<User> users = userRepository.findAll();
assertThat(users).asList().hasSize(1);
User actualUser = users.get(0);
User expectedUser = expectedUser();
assertThat(actualUser.getId()).isEqualTo(expectedUser.getId());
assertThat(actualUser.getName()).isEqualTo(expectedUser.getName());
assertThat(actualUser.getLastName()).isEqualTo(expectedUser.getLastName());
}
private User expectedUser() {
User expectedUser = new User();
expectedUser.setId(1L);
expectedUser.setName("John");
expectedUser.setLastName("Doe");
return expectedUser;
}
}
package com.example.h2_demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class H2DemoApplication {
public static void main(String[] args) {
SpringApplication.run(H2DemoApplication.class, args);
}
}
package com.example.h2_demo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
package com.example.h2_demo;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "users")
@Setter
@Getter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "last_name")
private String lastName;
}
CREATE TABLE IF NOT EXISTS users(
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL,
last_name VARCHAR(50)
);
INSERT INTO users
VALUES (1, 'John', 'Doe');
# application-test.properties
# show SQL executed by Hibernate
spring.jpa.properties.hibernate.show_sql=true
# show meta comments in Hibernate statements (as specified by org.springframework.data.jpa.repository.Meta annotations)
spring.jpa.properties.hibernate.use_sql_comments=true
# to enable line breaks and indentation in logged queries executed by Hibernate
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.type=trace
logging.level.org.springframework.jdbc.core=TRACE
# to see what @Sql scripts are executed
logging.level.org.springframework.test.context.jdbc=DEBUG
# to see what @Sql statements are executed
logging.level.org.springframework.jdbc.datasource.init=DEBUG
测试结果:
org.opentest4j.AssertionFailedError:
expected: "John"
but was: "Doe"
Expected :"John"
Actual :"Doe"
型
从日志中:
Hibernate:
drop table if exists users cascade
Hibernate:
create table users (
id bigint generated by default as identity,
last_name varchar(255),
name varchar(255),
primary key (id)
)
型
看到没?Hibernate打乱了列的顺序。当然,我可以禁用ddl-auto
(或者在DML脚本中指定列),但我很好奇为什么Hibernate会在这么简单的任务上失败。从来没有见过这样的事情。Hibernate保证表列的创建顺序与相应实体中的字段完全相同吗?如果不是,为什么不呢?这完全超出了我的理解能力
1条答案
按热度按时间luaexgnf1#
这在official user guide中并不明显,但不,Hibernate并不能保证这一点
如果hibernate.hbm2ddl.auto配置设置为create,Hibernate将生成以下数据库模式:
示例323.自动生成的数据库模式
字符串
后来在指南中…
示例335. @LazyGroup示例
型
注意顺序,这种不匹配意味着Hibernate会按照它认为合适的方式创建表列