web-dev-qa-db-fra.com

Hibernate @Formula n'inclut pas Schema

J'ai une entité avec une propriété @Formula comme ceci:

@Entity
@Table(name = "areasAuxiliar")
public final class AreaAuxiliar implements Serializable {

    @Id
    @Column(name = "idArea")
    private Integer idArea;

    @Formula("RUTAAREA(idArea)")
    private String ruta;

lorsque je configure mon hibernation pour qu'il pointe vers une base de données Oracle, je n'ai aucun problème, MAIS, lorsque je passe à un serveur SQL, hibernate n'inclut pas le shema et la requête échoue,

la requête générée pour hibernation ressemble à ceci:

select
    areaauxili4_.idArea as idArea1_6_4_,
    rutaArea(areaauxili4_.idArea) as formula2_4_
from
    SIGAP.areasAuxiliar areaauxili4_ 

le param hibernate.default_schema = SIGAP est en cours de lecture et est inclus dans le tableau mais pas dans la fonction,

existe-t-il une option/annotation pour forcer le shema dans cette fonction?

J'ai essayé d'hiberner 5.1 et 5.2 avec le même résultat :(

9
Alfredo M

Vous pouvez utiliser un fichier mysql-orm.xml pour remplacer votre formule, puis configurez votre construction pour tenir compte du fichier lorsque la base de données est mysql.

En remplaçant ici la formule:

<entity-mappings
    xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm orm_2_1.xsd"
    version="2.1">
    <package>com.acme.persistence</package>
    <entity class="AreaAuxiliar" access="FIELD">
        <attributes>
            <property name="ruta" formula="schemaName.RUTAAREA(idarea)"/>
        </attributes>
    </entity>
</entity-mappings>

Ajoutez ensuite la référence dans un persistence.xml spécifique. Vous remplacez ensuite votre persistence.xml par défaut par celui-ci dans votre construction ou à l'exécution (voir les liens ci-dessous).

<persistence
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">

<persistence-unit name="persistenceUnit">

    <provider>
        org.hibernate.jpa.HibernatePersistenceProvider
    </provider>

    <mapping-file>
        mappings/identifier/global/mysql-orm.xml
    </mapping-file>

    <class>
        com.acme.persistence.AreaAuxiliar 
    </class>

</persistence-unit>

Remarque: inspiré de Comment changer l'identifiant Hibernate GenerationType en fonction de la base de données sous-jacente

Note (2): Dans le blog post et here , l'auteur génère PersistenceUnitInfo au moment de l'exécution.

4
Laurent B

Vous ne savez pas si cela aide à appliquer la fonction, mais avez-vous déjà essayé d'ajouter la propriété 'schéma' à l'annotation @Table:

@Entity
@Table(name = "areasAuxiliar", schema="mySchemaName")
public final class AreaAuxiliar implements Serializable {

    @Id
    @Column(name = "idArea")
    private Integer idArea;

    @Formula("RUTAAREA(idArea)")
    private String ruta;

Une autre solution, convertie en commentaire, consiste à utiliser un espace réservé dans l'annotation @Formula.

@Entity
@Table(name = "areasAuxiliar")
public final class AreaAuxiliar implements Serializable {

    @Id
    @Column(name = "idArea")
    private Integer idArea;

    @Formula("{SCHEMA_AND_FUNCTION}")
    private String ruta;

Ajoutez ensuite un intercepteur pour renseigner la valeur de la formule. Le lien vers la solution est Hibernate @Formula a défini la valeur à l'exécution

Enfin, consultez mon commentaire sur la création d’une fonction globale dans SQLSERVER. Les détails peuvent être trouvés ici Puis-je créer une fonction globale dans SQL Server?

2
Dan

1) Je sais que pour les requêtes native , vous pouvez utiliser l’espace réservé "{h-schema}" (qui sera renseigné avec la valeur du paramètre "hibernate.default_schema"):

"SELECT x FROM {h-schema}tableName"

Essayez et voyez si, par hasard, cela fonctionne aussi dans @Formule ...

2) Sinon, vous pouvez aussi essayer de jouer avec des substitutions (c'est-à-dire hibernate.query.substitutions) afin de dire à hibernate de remplacer le S littéral par S '- dans votre cas, "RUTAAREA" avec "schema.RUTAAREA"?

0
TacheDeChoco