Hibernate LocalDateTime:Postgresql 模式生成在外部 Tomcat 中创建类型为“bytea”的列

Posted

技术标签:

【中文标题】Hibernate LocalDateTime:Postgresql 模式生成在外部 Tomcat 中创建类型为“bytea”的列【英文标题】:Hibernate LocalDateTime: Postgresql schema generation creates columns of type "bytea" in external Tomcat 【发布时间】:2018-01-30 11:26:10 【问题描述】:

我的 webapp 的 postgresql 数据库的休眠模式生成存在问题,该 webapp 托管在外部 tomcat (8.5.20) 中。 为此,我在我的 Spring Boot 应用程序中将 spring.jpa.hibernate.ddl-auto 设置为 create-drop。 当我使用嵌入式 tomcat 在我的 Eclipse 中运行应用程序时,所有 LocalDateTime 列都生成为 timestamp without time zone 这很好。 但是当生成war文件并部署到激活模式生成的外部tomcat时,所有这些列都生成为类型 bytea.

我试图定义在 context.xml 中链接的全局 jndi 资源 (server.xml),只有基于 context.xml 的 jndi 资源和 spring.data 和 spring.jpa 配置,当我在我的应用程序中运行 eclipse 时。特性。但是,一旦我将生成的战争部署到我的外部 tomcat,这些列就会生成为 bytea。

我也把postgresql-42.1.1.jar放到tomcat的lib文件夹下也没有成功。

这些是我对本地环境的设置,可以正常工作:

spring.datasource.url= jdbc:postgresql://localhost:5432/test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.hibernate.use-new-id-generator-mappings=true
spring.jpa.hibernate.ddl-auto=create-drop

这是在 context.xml 中定义 tomcat jndi 数据源的示例,它生成 bytea 列:

<Resource name="jdbc/test" auth="Container"
    type="javax.sql.DataSource" maxActive="20" maxIdle="5" maxWait="10000"
    username="postgres" password="postgres" driverClassName="org.postgresql.Driver"
    url="jdbc:postgresql://localhost:5432/test">
</Resource>

在这种情况下,我的应用程序属性如下所示:

spring.datasource.jndi-name=java:comp/env/jdbc/test
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.hibernate.use-new-id-generator-mappings=true
spring.jpa.hibernate.ddl-auto=create-drop

我最后尝试的是构建并运行生成的 jar。再次生成类型为“bytea”的列。因此,将列生成为时区的唯一变体是在 eclipse 中运行应用程序...

有人有想法吗?

【问题讨论】:

【参考方案1】:

一般不应该工作。是的,使用了 BLOB 约定。 Java8 LocalDateTime 不是 JPA 2.1 的正式组成部分

问题是为什么一个配置是积极的?我几乎可以肯定,PostgreSQL 没有任何问题。

也许你有更新/旧的休眠版本?较新的 Hibernate 版本可能有“早期版本”?纯属推测,我是最近几年的Eclipselink用户,Eclipselink没有实现。

一般建议且经过验证的良好方法是 JPA 类型转换器

@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> 

    @Override
    public Date convertToDatabaseColumn(LocalDate locDate) 
        return (locDate == null ? null : Date.valueOf(locDate));
    

    @Override
    public LocalDate convertToEntityAttribute(Date sqlDate) 
        return (sqlDate == null ? null : sqlDate.toLocalDate());
    

编辑:也许你在一些 JAR 中有这样的转换器,所以自动被强制???

EDIT2:Adam Bien 的代码和理论也许更好?

http://www.adam-bien.com/roller/abien/entry/new_java_8_date_and

【讨论】:

我刚刚发现:使用 @Column(columnDefinition= "timestamp without time zone") 注释我的实体中的 LocalDateTime 属性有效......但仍然不知道为什么我需要 i> 为除我的 eclipse 环境之外的所有环境执行此操作.... 在我看来每次手动“入侵”JPA 都不太好,个人不喜欢“columnDefinition”。在这种情况下创建是可以的,但是真正的操作呢?你检查了吗? 它是 JPA 2.2 的一部分,所以如果您的 JPA 提供商支持它,那么实际上应该“开箱即用”地支持它 @BillyFrost 同意,并等待期待已久的 JPA 2.2(尚未正式发布 - 08.2017)和 JEE8 的下一部分。类型转换器(来自 JPA 2.0 ???)非常好,并且使用 Joda DateTime 多年来经过测试 嗯,JPA 2.2 中的内容是官方和批准的,一些提供商支持它的全部或部分(DataNucleus 可以做所有事情,EclipseLink 做的最多,如果不是全部,从我所看到的来看,Hibernate 最新的有 java.time IIRC 类型)。 AttributeConverter 来自 JPA 2.1,是一个完全可用的解决方法

以上是关于Hibernate LocalDateTime:Postgresql 模式生成在外部 Tomcat 中创建类型为“bytea”的列的主要内容,如果未能解决你的问题,请参考以下文章

在数据库中使用Java 8 LocalDate和LocalDateTime进行Hibernate

Hibernate LocalDateTime:Postgresql 模式生成在外部 Tomcat 中创建类型为“bytea”的列

@CreationTimestamp 和 @UpdateTimestamp 不适用于 LocalDateTime

LocalDateTime

Spring Boot 1.4:LocalDateTime 映射到 varbinary 而不是时间戳类型

Java String 转 LocalDateTime