Spring Boot 和 Postgres:关系“sub_comment”不存在

Posted

技术标签:

【中文标题】Spring Boot 和 Postgres:关系“sub_comment”不存在【英文标题】:Spring Boot & Postgres: relation "sub_comment" does not exist 【发布时间】:2018-10-19 05:57:47 【问题描述】:

我有两个实体:CommentSubComment。一个Comment 可以有多个SubComments。我正在尝试与 Hibernate 建立一对多/多对一的双向关系。

我不知道出了什么问题。这两个表似乎都已在 PSQL 中正确创建。

Comment.java

import javax.persistence.*;
import java.util.Set;

@Entity
public class Comment 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column
    private String text;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "comment")
    private Set<SubComment> subComment;

    public long getId() 
        return id;
    

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

    public String getText() 
        return text;
    

    public void setText(String text) 
        this.text = text;
    

SubComment.java

import javax.persistence.*;

@Entity
public class SubComment 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String text;

    @ManyToOne
    private Comment comment;

    public long getId() 
        return id;
    

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

    public String getText() 
        return text;
    

    public void setText(String text) 
        this.text = text;
    

    public Comment getComment() 
        return comment;
    

    public void setComment(Comment comment) 
        this.comment = comment;
    

我收到此错误:

通过 JDBC 语句执行 DDL 时出错原因: org.postgresql.util.PSQLException:错误:关系“sub_comment”确实 不存在

Hibernate: create table "user" (id  bigserial not null, email varchar(255), name varchar(255), username varchar(255), primary key (id))
Hibernate: create table comment (comment_id  bigserial not null, text varchar(255), primary key (comment_id))
Hibernate: create table sub_comment (sub_comment_id  bigserial not null, text varchar(255), comment_comment_id int8, primary key (sub_comment_id))
Hibernate: alter table sub_comment add constraint FK87789n34vmns9eeyw6jgc5ghp foreign key (comment_comment_id) references comment

application.properties

spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:postgresql://localhost:5432/dbname
spring.datasource.data-username=username
spring.datasource.driver-class-name=org.postgresql.Driver

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false

【问题讨论】:

发布您的整个日志跟踪。 你的问题解决了吗? 在问题中向您发布 DAO 类和服务类。 你有一个可以接受的答案。 【参考方案1】:

你错过了@JoinColumn。由于基于字段的访问,您将收到另一个错误。改用基于属性的访问:

import javax.persistence.*;

@Entity
@Table(name = "subcomment")
public class SubComment implements Serializable 

    private static final long serialVersionUID = -3009157732242241606L;

    private long id;
    private String text;
    private Comment comment;

    @Id
    @Column(name = "sub_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() 
        return id;
    

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

    @Basic
    @Column(name = "sub_text")
    public String getText() 
        return text;
    

    public void setText(String text) 
        this.text = text;
    

    @ManyToOne
    @JoinColumn(name = "sub_fk_c_id", referencedColumnName = "c_id") // here the exact field name of your comment id in your DB
    public Comment getComment() 
        return comment;
    

    public void setComment(Comment comment) 
        this.comment = comment;
    

也在这里进行更改:

import javax.persistence.*;

@Entity
@Table(name = "comment")
public class Comment implements Serializable 

    private static final long serialVersionUID = -3009157732242241606L;    

    private long id;
    private String text;
    private Set<SubComment> subComment = new HashSet<>();

    @OneToMany(mappedBy = "comment", targetEntity = SubComment.class)
    public Set<SubComment> getSubComment() 
        return subComment;
    

    public void setSubComment(Set<SubComment> subComment) 
        this.subComment = subComment;
    

    @Id
    @Column(name = "c_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() 
        return id;
    

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

    @Basic
    @Column(name = "c_text")
    public String getText() 
        return text;
    

    public void setText(String text) 
        this.text = text;
    

将以下内容粘贴到您的 application.properties 文件中:

spring.jpa.properties.hibernate.id.new_generator_mappings = false
spring.jpa.properties.hibernate.format_sql = true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.jpa.hibernate.ddl-auto=create

在你的 pom.xml 文件中粘贴这些:

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>

更多参考请参见this *** post。

【讨论】:

尝试了您的修复(复制和粘贴),结果相同...org.postgresql.util.PSQLException: ERROR: relation "sub_comment" does not exist 添加了另一个编辑。它肯定可以通过删除现有表并创建新表来工作。 如果解决方案有效,请接受答案作为解决方案并投票。 同样的结果,sub_comment does not exist。为什么我会由于基于字段的访问而出错。什么时候使用基于字段和基于属性? 将您的 application.properties 文件内容添加到您的问题中。【参考方案2】:

许多子 cmets 属于一个评论,模型应该是这样的(comment_id 你可以生成,例如 UUID.randomUUID().toString())

@Entity
@Table(name = "comment")
public class Comment

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "comment_id")
String commentId;



@Entity
@Table(name = "sub_comment")
public class SubComment

...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "comment_id", referencedColumnName = "comment_id")
Comment comment;
...

如果您使用例如 Liquidbase 来控制您的数据源:

  - changeSet:
      id: 1
      author: author.name
      changes:
      - addForeignKeyConstraint:
          baseColumnNames: comment_id
          baseTableName: sub_comment
          constraintName: fk_comment_subcomment
          referencedColumnNames: comment_id
          referencedTableName: comment

【讨论】:

我想请你看看这个 *** 解决方案***.com/a/44055520/7538821 您的链接有什么共同问题?如果你的意思是我现在想念 getter/setter,Lombok 会处理这个问题,我只提供一个通用解决方案,而不是整个实现。 如果您使用多对一注释进行基于字段的属性访问,则项目甚至无法编译,并且此错误仍在休眠 5 中。基于属性的访问是唯一的解决方案。 你可以参考这里thoughts-on-java.org/… 很遗憾,你错了。我不知道 Hibernate 魔术在幕后做了什么,但连接列名可以有一个存在于 DB 中的名称。这是我在真实环境中工作的代码。【参考方案3】:

我知道这个答案已经晚了,但也许它会对某人有所帮助,他们的问题是他们没有配置架构,这就是他们抛出该错误的原因。

这里是如何在 postgresql 中配置模式:

spring.jpa.properties.hibernate.default_schema = "his schema"

【讨论】:

【参考方案4】:

有一个类似的问题,我的问题是我的 SubCategory 类下缺少 referencedColumnName。

有这个

  @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
    @JoinColumn(name = "category_id, nullable = false)
    private Category category;

而不是

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
    @JoinColumn(name = "category_id", referencedColumnName = "id", nullable = false)
    private Category category;

所以我的子类别表没有被创建。

【讨论】:

以上是关于Spring Boot 和 Postgres:关系“sub_comment”不存在的主要内容,如果未能解决你的问题,请参考以下文章

dockerized postgres 和 dockerized Spring boot app

使用 spring boot 和 postgres 正确设置 docker compose

带有用户名和密码的 Zonky + Spring Boot + Postgres + Flyway

Liquibase / Spring Boot / Postgres - 模式名称不起作用

Spring Boot - MySQL 到 Postgres 的迁移

Docker Compose (TOMCAT + POSTGRES) - Spring Boot 应用程序:容器之间的连接问题