Hibernate:将字符串映射到 TEXT 而不是 VARCHAR

Posted

技术标签:

【中文标题】Hibernate:将字符串映射到 TEXT 而不是 VARCHAR【英文标题】:Hibernate: Map String to TEXT instead of VARCHAR 【发布时间】:2019-06-05 16:24:03 【问题描述】:

我目前正在为一门课程做作业。想法是构建一个简单的类似 Twitter 的后端和前端。对于这个项目,我们得到了一个包含三个 maven 模块的预构建项目:

业务(实际 API) 持久性(模型) 演示文稿(网站)

这个项目使用 h2 作为hibernate 的数据库来简化开发。 预构建的东西工作得很好,但是为了您自己的服务,我定义了这个帖子模型:

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.json.bind.annotation.JsonbDateFormat;
import javax.persistence.*;
import java.util.Date;

@EqualsAndHashCode(callSuper = true)
@Entity
@Data
public class DBPost extends DBIdentified 

    private String message;
    private String author;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonbDateFormat(value = JsonbDateFormat.TIME_IN_MILLIS)
    private Date creationDate;

    public DBPost() 
    


数据库识别:

import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
public class DBIdentified 

    private long id;

    @Id
    @GeneratedValue
    public long getId() 
        return this.id;
    

    public void setId(final long id) 
        this.id = id;
    


StartupBean:

@PostConstruct
    public void startup() 

        final DBPost firstPost = this.entityManager.find(DBPost.class, 1L);

        // only initialize once
        if (firstPost == null) 
            final DBPost post = new DBPost();

            post.setUrl("https://dl.gitea.io/gitea/1.8.2/");
            post.setAuthor("Gitea");
            post.setUrgent(false);
            post.setVersion("1.8.2");
            post.setCreationDate(new Date());
            post.setMessage("BUGFIXES\n" +
                    "\n" +
                    "    Fix possbile mysql invalid connnection error (#7051) (#7071)\n" +
                    "    Handle invalid administrator username on install page (#7060) (#7063)\n" +
                    "    Disable arm7 builds (#7037) (#7042)\n" +
                    "    Fix default for allowing new organization creation for new users (#7017) (#7034)\n" +
                    "    SearchRepositoryByName improvements and unification (#6897) (#7002)\n" +
                    "    Fix u2f registrationlist ToRegistrations() method (#6980) (#6982)\n" +
                    "    Allow collaborators to view repo owned by private org (#6965) (#6968)\n" +
                    "    Use AppURL for Oauth user link (#6894) (#6925)\n" +
                    "    Escape the commit message on issues update (#6901) (#6902)\n" +
                    "    Fix regression for API users search (#6882) (#6885)\n" +
                    "    Handle early git version's lack of get-url (#7065) (#7076)\n" +
                    "    Fix wrong init dependency on markup extensions (#7038) (#7074)\n");

            this.entityManager.persist(post);
        
    

当我尝试在数据库中(在业务模块的 Bean 中)插入帖子时,我收到以下错误消息:

Caused by: org.h2.jdbc.JdbcSQLException: Value too long for column "MESSAGE VARCHAR(255)": "STRINGDECODE('BUGFIXES\n\n    Fix possbile mysql invalid connnection error (#7051) (#7071)\n    Handle invalid administrator use... (790)"; SQL statement:

我想我需要将数据库中的消息类型更改为 TEXTLONGTEXT

但是所有这些注释private String message的方法都失败了:

@Type(type="text") @Column(length= Integer.MAX_VALUE) @Column(columnDefinition="CLOB") @Column(columnDefinition="TEXT") @Column(length=65535, columnDefinition="Text") @Lob

问题可能出在不同的模块上,而持久性模块被包含在业务模块中吗?还是我只是在休眠方面做错了什么?

【问题讨论】:

【参考方案1】:

这是你需要的注解:

@Column(columnDefinition="TEXT")

【讨论】:

这也不起作用,我将其添加到测试变体列表中 这个注释的结果是什么? 你可以试试这个@DerMolly:@Column(length = 65535,columnDefinition="Text") @SimonMartinelli ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (ServerService Thread Pool -- 15) Value too long for column "MESSAGE VARCHAR(255)": "STRINGDECODE('BUGFIXES\n\n Fix possbile mysql invalid connnection error (#7051) (#7071)\n Handle invalid administrator use... (790)"; SQL statement: @Macanga 同样的问题。相同的消息。【参考方案2】:

经过一番搜索,我得到了答案:

DBIdentified 中,getter 被注释,在DBPost 中,字段被注释。混合使用 field 和 getter 注解是行不通的,因为 hibernate 会搜索 @Id 注解并假设一切都像它一样。

所以修复是

DBIdentified:

import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
public class DBIdentified 

    @Id
    @GeneratedValue
    private long id;

    public long getId() 
        return this.id;
    

    public void setId(final long id) 
        this.id = id;
    


【讨论】:

以上是关于Hibernate:将字符串映射到 TEXT 而不是 VARCHAR的主要内容,如果未能解决你的问题,请参考以下文章

JPA/Hibernate 将简单字符串或任意对象映射到 mysql 日期类型?

将 PostgreSQL JSON 列映射到 Hibernate 实体属性

将 [name,value] 字符串值映射到类而不进行反射

如何使用 JPA 和 Hibernate 映射 PostgreSQL 枚举

Hibernate持久化对象的状态

Grails (Hibernate) java.time.ZoneId 到数据库的映射