我有一个使用hibernate映射到postgres数据库的模型类。我的模型类是:
@Entity
@Table(name="USER")
public class User {
@Id
@GeneratedValue
@Column(name="id")
private long id;
@Column(name="username", unique=true)
private String username;
@Column(name="email")
private String email;
@Column(name="created")
private Timestamp created;
public User(long id, String username, String email) {
this.id = id;
this.username = username;
this.email = email;
}
}
我尝试使用以下查询检索用户名为“adam”的用户:
tx = session.beginTransaction();
TypedQuery<User> query = session.createQuery("FROM User u WHERE u.username = :username", User.class).setParameter("username", "adam");
user = query.getSingleResult();
我得到一个例外:
org.postgresql.util.PSQLException: ERROR: column user0_.id does not exist
我的bash shell数据库如下:
hibernate如何将类属性映射到表列?它是仅基于@Column(name="username")
匹配还是根据数据类型和约束(例如唯一/自动增量)尝试匹配?
答案 0 :(得分:25)
它给你这个错误:
org.postgresql.util.PSQLException: ERROR: column user0_.id does not exist
因为当您创建数据库PostgreSQL时,它会创建一个名为public
的默认架构,所以当您不在Entity
中指定名称时,它将在公共架构中自动检查,因为你得到这个错误。
另一件事确认架构名称是正确的,错误说:
column user0_.id does not exist
而不是:
column myapp.user0_.id does not exist
-------^----^
确认查询使用的是public schema
而不是真正的schema myapp
要解决此问题,您必须指定架构的名称,如下所示:
@Table(name="USER", schema = "myapp")
请勿在PostgreSQL中的表或列名称中使用大写字母。
@Table(name="user", schema = "myapp")
和用户名称是PostgreSQL中的保留关键字look at
答案 1 :(得分:1)
对于遇到此异常的人,在postgres中,每当您编写一个Entity Class时,都尝试将其与正确的架构(存在表的地方)相关联,如下所示:
@Entity
@Table(name = "user", schema = "users_details")
public class User implements Serializable{
@Column(name = "id")
Long id; //long is not recommended
// Other data
}
如@YCF_L所说,不要在表名或列名中使用大写字母,否则您将收到此异常。
当您必须从实体类中自动自动生成表时,反之亦然。
答案 2 :(得分:1)
应在Entity类上添加架构名称。 对于此示例,当架构名称为public
时@Table(name = "user", schema = "public")
请参见下面的PostgreSQL Admin视图
有关SpringBoot Java和Postgre SQL连接的更多信息,请参见此处: https://cmsoftwaretech.wordpress.com/2020/04/25/springboot-thymleaf-using-postgresql/
答案 3 :(得分:1)
我使用user
之类的通用名称获取的信息正在应用程序中引起麻烦。
我遇到了与以下简单实体相同的问题。
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
@Entity
public class User implements Serializable {
private static final long serialVersionUID = 6843302791607583447L;
@Id
@SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
private Long id;
@Column
private String name;
@Column
private String password;
@Override
public String toString() {
return name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(final String password) {
this.password = password;
}
}
我所做的就是将实体从User
重命名为Sessionxuser
(并将数据表从user
重命名为sessionxuser
来解决此问题。
架构仍为public
。
由于某些名称的前缀或后缀,例如mycoolappuser
或usermycoolapp
,以避免出现此类麻烦。
在列表下方找到保留的关键字和文字,以防止用作表,列和其他自定义名称。
https://www.postgresql.org/docs/8.1/sql-keywords-appendix.html
在这种情况下,为user
,PostgreSQL
,SQL:2003
和SQL:1999
保留了SQL-92
。
答案 4 :(得分:0)
使用:@GeneratedValue(strategy = GenerationType.IDENTITY)
在您的POJO类ID字段中。这件事解决了我的错误。
答案 5 :(得分:0)
尝试从pg管理控制台(drop table schema_name.table_name
)中删除表,并确保正确注释了您的实体类。例如,实体类上的@Table(name = "table_name", schema = "schema_name")
答案 6 :(得分:0)
除了之前所有的正确答案,我想说@Column 和@GeneratedValue 注释的定位也很重要。您希望在特定字段或 getter 方法上方拥有这两个注释,但不能分开(not 一个注释位于 getter 上方,另一个注释位于字段上方)。至少对我有用。