web-dev-qa-db-fra.com

Comment mapper des champs d'entité Hibernate en utilisant camelCase à des identificateurs de base de données snake_case (underscore)

J'ai des champs de base de données en souligné. J'ai des champs d'entité dans camelcase. Je ne peux changer ni l'un ni l'autre.

Y a-t-il quelque chose, peut-être une annotation au niveau de la classe que je peux utiliser pour annoter le nom de colonne d'entité par défaut à l'équivalent camelcase?

par exemple, j'ai une entité comme celle-ci:

@Entity
public class AuthorisationEntity {

    @Column(name = "non_recoverable")
    private BigDecimal nonRecoverable;

    @Column(name = "supplier_recoverable")
    private BigDecimal supplierRecoverable;

    @Column(name = "refund_amount")
    private BigDecimal refundAmount;

}

J'en rêve:

@Entity
@DatabaseIsUnderscoreAndThisAnnotationConvertsThemToCamelCaseByDefault
public class AuthorisationEntity {

    private BigDecimal nonRecoverable;

    private BigDecimal supplierRecoverable;

    private BigDecimal refundAmount;

}
27
Paul Stanley

Vous pouvez utiliser la stratégie de nommage d'Hibernate. Une telle classe de stratégie de dénomination décrit comment générer des noms de base de données pour des noms Java Java donnés).

Voir:

exemple de stratégie de nommage

deuxième exemple

très bonne stratégie de nommage Oracle - il convertit le chameau en convention de soulignement, et bien plus encore

13
przemek hertel

Comme je l'ai expliqué dans cet article , vous pouvez y parvenir en utilisant une stratégie de nommage Hibernate personnalisée.

Il vous suffit d'utiliser le hibernate-types projet open-source.

Hibernate 5.2 ou version ultérieure

Vous devez ajouter la dépendance Maven suivante:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>${hibernate-types.version}</version>
</dependency>

Et définissez la propriété de configuration Hibernate suivante:

<property name="hibernate.physical_naming_strategy"
          value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"
/>

Hibernate 5.0 et 5.1

Vous devez ajouter la dépendance Maven suivante:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-5</artifactId>
    <version>${hibernate-types.version}</version>
</dependency>

Et définissez la propriété de configuration Hibernate suivante:

<property name="hibernate.physical_naming_strategy"
          value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"
/>

Hibernate 4.3

Vous devez ajouter la dépendance Maven suivante:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-43</artifactId>
    <version>${hibernate-types.version}</version>
</dependency>

Et définissez la propriété de configuration Hibernate suivante:

<property name="hibernate.ejb.naming_strategy"
          value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"
/>

Hibernate 4.2 et 4.1

Vous devez ajouter la dépendance Maven suivante:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-4</artifactId>
    <version>${hibernate-types.version}</version>
</dependency>

Et définissez la propriété de configuration Hibernate suivante:

<property name="hibernate.ejb.naming_strategy"
          value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"
/>

Temps de test

En supposant que vous disposez des entités suivantes:

@Entity(name = "BookAuthor")
public class BookAuthor {

    @Id
    private Long id;

    private String firstName;

    private String lastName;

    //Getters and setters omitted for brevity
}

@Entity(name = "PaperBackBook")
public class PaperBackBook {

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

    @NaturalId
    private String ISBN;

    private String title;

    private LocalDate publishedOn;

    @ManyToOne(fetch = FetchType.LAZY)
    private BookAuthor publishedBy;

    //Getters and setters omitted for brevity
}

Lors de l'utilisation de la stratégie de dénomination personnalisée CamelCaseToSnakeCaseNamingStrategy, Hibernate va générer le schéma de base de données suivant à l'aide de hbm2ddl outil:

CREATE SEQUENCE hibernate_sequence
START WITH 1 INCREMENT BY 1

CREATE TABLE book_author (
    id          BIGINT NOT NULL,
    first_name  VARCHAR(255),
    last_name   VARCHAR(255),
    PRIMARY KEY (id)
)

CREATE TABLE paper_back_book (
    id              BIGINT NOT NULL,
    isbn            VARCHAR(255),
    published_on    DATE, 
    title           VARCHAR(255),
    published_by_id BIGINT, 
    PRIMARY KEY (id)
)

Cool, non?

7
Vlad Mihalcea
import org.hibernate.cfg.DefaultNamingStrategy;
import org.hibernate.cfg.ImprovedNamingStrategy;

public class NamingStratagyTest {
    public static void main(String[] args) {
        String colName = DefaultNamingStrategy.INSTANCE.columnName("UserName");
        System.out.println(colName); // UserName
        colName = ImprovedNamingStrategy.INSTANCE.columnName("UserName");
        System.out.println(colName);// user_name
    }
}

Voilà, choisissez la stratégie de dénomination qui convient à vos besoins.

1
zawhtut

Je rencontrais le même problème dans une application Spring Boot, j'ai essayé d'ajouter la configuration Hibernate ci-dessus au fichier de propriétés Spring sans succès, je l'ai ajoutée en tant que bean Java, encore une fois sans succès.

J'utilise Hibernate Properties object, en ajoutant la configuration hibernate dans ceci a résolu mon problème:

        protected Properties buildHibernateProperties() {
        Properties hibernateProperties = new Properties();
        hibernateProperties.setProperty("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
        hibernateProperties.setProperty("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());

        return hibernateProperties;
    }
0
Leroy