Hibernate @Formula не включает схему

у меня есть объект со свойством @Formula такой:

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

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

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

когда я настраиваю свой спящий режим, чтобы указать на Oracle DB, у меня нет проблем, Но, когда я переключаюсь на SQLServer, hibernate не включает Шма и запрос не выполняется,

запрос, сгенерированный для hibernate, выглядит следующим образом:

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

парам спящий режим.default_schema=SIGAP читается и включены в таблицу, но не в функции

есть ли опция / аннотация, чтобы заставить shema в этой функции?

Я пробовал hibernate 5.1 и 5.2 с тем же результатом: (

4 ответов


можно использовать mysql-orm.xml файл, чтобы переопределить формулу, затем настройте свою сборку на tale с учетом файла, когда база данных mysql.

переопределяя здесь формулу:

<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>

затем добавьте ссылку в конкретный persistence.xml. Затем переопределите сохраняемость по умолчанию.xml с этим в вашей сборке или во время выполнения (см. ссылки ниже).

<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>

Примечание : heavlily воодушевленный от как изменить спящий режим Идентификатор GenerationType в зависимости от базовой базы данных

примечание (2) : в блоге и здесь, автор генерирует PersistenceUnitInfo во время выполнения.


не уверен, что это помогает применить к функции, но вы пытались добавить свойство "schema" в @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;

другое решение, которое было преобразовано в комментарий, заключается в использовании держателя места в @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;

затем добавьте перехватчик для заполнения значения формулы. Ссылка на решение Hibernate @Formula установить значение во время выполнения

наконец, см. Мой комментарий о создании глобальная функция в SQLSERVER. Подробности можно найти здесь можно ли создать глобальную функцию в SQL Server?


1) я знаю, что для уроженца запросы, вы можете использовать заполнитель" {h-schema} "(который будет заполнен значением " hibernate.default_schema " param):

"SELECT x FROM {h-schema}tableName"

попробуйте и посмотрите, случайно ли это также работает в @Formula...

2) Если нет, вы также можете попробовать играть с заменами (i.e спящий режим.запрос.замены), чтобы сказать hibernate заменить литерал S на S' - в вашем случае "RUTAAREA" на " schema.RUTAAREA" ?


более упрощенное решение:

измените свою формулу @из этого:

@Formula("RUTAAREA(idArea)")

для этого:

@Formula("{MYAPP_SCHEMA}.RUTAAREA(idArea)")

создать класс:

public class HibernateEntityInterceptor extends EmptyInterceptor {

}

зарегистрируйте его как перехватчик сущности в вашем sessionFactory, в моем случае:

sessionFactory.setEntityInterceptor(new HibernateEntityInterceptor());

затем в этом классе можно переопределить этот метод:

public String onPrepareStatement(String sql) {

этот метод возвращает команду sql до ее выполнения, поэтому все, что вам нужно сделать, это просто заменить все:

sql = sql.replaceAll("\{MYAPP_SCHEMA}", default_schema);
return sql;

thanx за помощь.