在冬眠初始化之前加载弹簧属性

发布于 2025-02-06 23:35:16 字数 2110 浏览 2 评论 0原文

在我的JPA-SpringBoot-App中,我必须支持不同的数据库,即Postgres和Oracle。我有一个具有LOB类型的实体,我想将数据存储为字符串。由于Postgres与其他数据库不同,因此我尝试选择取决于数据库方言的SQL类型,根据以下指示: https://geeknet.me/hibernate-postgresql-the-lob-annotation/

所以这就是我所拥有的:

@Entity
public class MyEntity {

    @EmbeddedId
    private MyPk myPk;

    @Lob
    @Column(name = "value", nullable = false)
    @Type(type = "org.example.DatabaseAwareLobType")
    private String value;
}

databaseawarelobtype看起来像:

import org.hibernate.type.descriptor.java.StringTypeDescriptor;
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
...

@Component
public class DatabaseAwareLobType extends AbstractSingleColumnStandardBasicType<String> {

    @Value("${spring.jpa.properties.hibernate.dialect}")
    private String dbDialect;

    private static String DBDIALECT_STATIC;

    public static final DatabaseAwareLobType INSTANCE = new DatabaseAwareLobType();

    public DatabaseAwareLobType() {
        super(getDbDescriptor(), StringTypeDescriptor.INSTANCE );
    }
    public static SqlTypeDescriptor getDbDescriptor() {
        if( isPostgres() ) {
            return VarcharTypeDescriptor.INSTANCE;
        }
        else {
            return ClobTypeDescriptor.DEFAULT;
        }
    }

    private static boolean isPostgres() {
        if(Objects.isNull(DBDIALECT_STATIC) ) {
            return false;
        }

        return DBDIALECT_STATIC.contains( "postgres" );
    }

    @Value("${spring.jpa.properties.hibernate.dialect}")
    public void setDbDialectStatic(String dbDialect) {
        DatabaseAwareLobType.DBDIALECT_STATIC = dbDialect;
    }

}

我的问题是:我的问题是 dbdialect resp。 dbdialect_static属性。它们没有值,因为在加载应用程序属性之前,请进行休眠初始化。

在链接的指令中,手动读取属性。我不能这样做,因为我不知道使用了哪个属性文件(不同的弹簧配置文件,通过Docker环境自定义)。

我搜索了加载属性事先启动,也许是为数据库类型初始化bean。但是我没有找到适合我的问题的解决方案。也许我以错误的方式尝试。

有人知道如何解决这个问题吗?感谢任何建议。

In my JPA-Springboot-app I have to support different databases, i.e. postgres and oracle. I have an entity with a lob type and i want to store the data as string. Because postgres stores lobs differently to other databases, I tried to choose the sql type dependent on the database dialect, according to these instruction: https://geeknet.me/hibernate-postgresql-the-lob-annotation/

So here is what i have:

@Entity
public class MyEntity {

    @EmbeddedId
    private MyPk myPk;

    @Lob
    @Column(name = "value", nullable = false)
    @Type(type = "org.example.DatabaseAwareLobType")
    private String value;
}

The DatabaseAwareLobType looks like:

import org.hibernate.type.descriptor.java.StringTypeDescriptor;
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
...

@Component
public class DatabaseAwareLobType extends AbstractSingleColumnStandardBasicType<String> {

    @Value("${spring.jpa.properties.hibernate.dialect}")
    private String dbDialect;

    private static String DBDIALECT_STATIC;

    public static final DatabaseAwareLobType INSTANCE = new DatabaseAwareLobType();

    public DatabaseAwareLobType() {
        super(getDbDescriptor(), StringTypeDescriptor.INSTANCE );
    }
    public static SqlTypeDescriptor getDbDescriptor() {
        if( isPostgres() ) {
            return VarcharTypeDescriptor.INSTANCE;
        }
        else {
            return ClobTypeDescriptor.DEFAULT;
        }
    }

    private static boolean isPostgres() {
        if(Objects.isNull(DBDIALECT_STATIC) ) {
            return false;
        }

        return DBDIALECT_STATIC.contains( "postgres" );
    }

    @Value("${spring.jpa.properties.hibernate.dialect}")
    public void setDbDialectStatic(String dbDialect) {
        DatabaseAwareLobType.DBDIALECT_STATIC = dbDialect;
    }

}

My problem are the dbDialect resp. DBDIALECT_STATIC properties. They have no value, because the hibernate initialization is done before loading the application properties.

In the linked instruction the properties were read manually. I cant to this, because i dont know which property file is used (different spring profiles, customization via docker environment).

I'm searched for loading properties prior application startup, maybe to initialize a bean for the database type. But I have found no suitable solution for my problem. Maybe I'm trying it the wrong way.

Does anyone have an idea how i can solve this? I am thankful for any suggestions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

林空鹿饮溪 2025-02-13 23:35:16

所以我没有找到解决方案。我有另一种实现。

首先,我将属性类型从字符串更改为字节[],并使用Hibernates二进制型将其映射,

@Entity
public class MyEntity {

    @EmbeddedId
    private MyPk myPk;

    @Lob
    @Column(name = "data", nullable = false)
    @Type(type="org.hibernate.type.BinaryType")
    private byte[] data;
}

然后用Liquibase设置了数据库。 LOB列不再来自类型的Clob,而是来自Blob。因此,我的liquibase-changelog看起来像:

<createTable tableName="my_entity" schemaName="importservice">
...
    <column name="data" type="${blob_type}">
        <constraints nullable="false" />
    </column>
</createTable>

lob类型的关联属性考虑了目标数据库:

<property name="blob_type" value="bytea" dbms="postgresql"/>
<property name="blob_type" value="blob"/>

因此,现在有一个额外的步骤可以转换字符串中的字节数组,反之亦然。但这对我来说是可以的。

So I have found no solution. I have an alternative implementation.

First I changed the attribute type from String to byte[] and used Hibernates BinaryType for mapping it

@Entity
public class MyEntity {

    @EmbeddedId
    private MyPk myPk;

    @Lob
    @Column(name = "data", nullable = false)
    @Type(type="org.hibernate.type.BinaryType")
    private byte[] data;
}

I set up the database with liquibase. The LOB column is no longer from type clob but from blob. So my liquibase-changelog looks like:

<createTable tableName="my_entity" schemaName="importservice">
...
    <column name="data" type="${blob_type}">
        <constraints nullable="false" />
    </column>
</createTable>

And the target database is taken into account by the associated properties for the lob type:

<property name="blob_type" value="bytea" dbms="postgresql"/>
<property name="blob_type" value="blob"/>

So now there is an extra step for converting the byte array in string and vice versa. But this is ok for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文