Hibernate 5.1.x命名策略(向后兼容Hibernate 4.x)

4
我正在使用Spring Boot 1.3.3.RELEASE。默认情况下,Spring Boot使用Hibernate Version 4.x。我试图使用新的Hibernate,即5.1.0 FINAL(截至目前)。
我正在使用Gradle,所以要覆盖Hibernate版本,我添加了以下行:
ext['hibernate.version']="5.1.0.Final"

我遵循了SpringBoot 1.3.0支持hibernate 5的步骤

我正在使用下面的命名策略

spring.jpa.properties.hibernate.naming.implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl

spring.jpa.properties.hibernate.naming.physical_strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

我有一个实体类

@Entity
public class AppUser {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @Length(max = 100)
    private String username;

    @NotNull
    @Length(max = 100)
    private String firstName;

    @NotNull
    @Length(max = 100)
    private String lastName;

    @Length(max = 100)
    private String middleName;

    @NotNull
    @Length(max=100)
    private String email;

    @NotNull
    @Length(max = 100)
    private String password;

    @NotNull
    private boolean enabled;

}

在 Hibernate 4.x 中,它执行查询。
create table app_user (
        id bigint not null auto_increment,
        email varchar(100) not null,
        enabled bit not null,
        first_name varchar(100) not null,
        last_name varchar(100) not null,
        middle_name varchar(100),
        password varchar(100) not null,
        username varchar(100) not null,
        primary key (id)
    )

在5.x版本中,它执行了查询操作。

create table AppUser (
        id bigint not null auto_increment,
        email varchar(100) not null,
        enabled bit not null,
        firstName varchar(100) not null,
        lastName varchar(100) not null,
        middleName varchar(100),
        password varchar(100) not null,
        username varchar(100) not null,
        primary key (id)
    )

如何设置命名策略,使Hibernate在表名和列名上使用5.x下划线(与4.x相同)


你确定已经使用ext['hibernate.version']="5.1.0.Final"将Hibernate版本更改为5.1.0吗?我认为你参考的链接中的解决方案适用于Maven,而不适用于Gradle。 - TheKojuEffect
当Classpath包含Hibernate 5.1.0.Final Jars时,返回“是”。 - A0__oN
2个回答

5
首先,您不需要使用org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl,因为它没有实际作用并且已被Hibernate默认使用。
Hibernate 5没有您需要的策略。所有的策略都符合JPA标准(生成类似于AppUser的名称)。因此,您需要自己实现。
以下是一个物理命名策略示例:
public class UnderscorePhysicalStartegy extends PhysicalNamingStrategyStandardImpl {

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return context.getIdentifierHelper()
                .toIdentifier(NamingStrategyUtils.classToName(name.getText()));
    }

}

它使用NamingStrategyUtils
请注意,如果您指定了显式名称。
@Entity
@Table(name = "AppUser")
public class AppUser {

}

你将拥有一个名为app_user的表。如果您不想使用此类行为,请使用隐式命名策略。
我对命名策略进行了一些研究。您可以参考Hibernate5NamingStrategy,它生成带下划线的表和列名称以及约束名称(唯一性、外键)。
该类用于生成名称:HibernateNamingStrategy如何使用Hibernate5NamingStrategy 命名策略可以使用StrategyOptions进行配置。
例如,要使用没有前缀(如f_)的策略:
StrategyOptions options = StrategyOptions.builder().withoutPrefixes().build();
Hibernate5NamingStrategy strategy = new Hibernate5NamingStrategy(options);

其他示例:Hibernate 5隐式命名策略 除此之外,Hibernate 5的ImprovedNamingStrategy可用于模拟Hibernate 4的ImprovedNamingStrategy行为。

有没有办法在不使用“f_”前缀的情况下使用它?对于默认设置来说,这真是让人恼火。 - Bassinator
@Airhead 我更新了我的回答。我不知道哪种默认行为更好使用。 - v.ladynev
最终我创建了自己的类,继承了提到的类并进行了配置,以便能够从persistence.xml中使用它,而不是使用已弃用的配置对象。 - Bassinator
1
@Airhead 很有趣。需要将这种方式添加到文档中。 - v.ladynev

0

我提供我的分析供任何人使用:

如果您在实体类中使用@Table@Column注释,并且使用下划线提供名称,例如user_id,即@Column(name="user_id"),它将采用列名为user_id;如果您将其命名为userid,则在不使用策略或隐式策略(特别是spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl)的情况下,它将更改为user_id。因此,如果您想要一种策略,使实体属性名称更改为带有下划线和小写字母的名称,例如从userId更改为user_id,则应使用隐式或无策略(实际上使用隐式策略)。

如果您不希望您的命名策略向列名或类名添加下划线,则需要使用的策略如下:spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl。您在注释@Table@Column的name属性中提供的内容将保持不变。

如果您不想提供注释,并想手动处理表名和列名,那么您应该扩展类org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl并覆盖所需的方法。如果您仍然在某些情况下使用注释,请记住重写的方法将应用于这些注释中编写的名称。spring.jpa.hibernate.naming.physical-strategy=example.CustomStrategy


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接