sql关键字作为jpa实体列名的用法
Posted
技术标签:
【中文标题】sql关键字作为jpa实体列名的用法【英文标题】:Sql keyword usage as a jpa entity column name 【发布时间】:2020-05-27 18:16:09 【问题描述】:我正在使用 JPA 和 PostgreSQL, 我有一个错误
org.postgresql.util.PSQLException: ERROR: syntax error at or near "default"
当我想更新现有数据时,却显示错误。如何检查导致此错误的原因是什么?
这是我的代码
Resume.java
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Table(name = "resume")
public class Resume extends AuditModel implements Serializable
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
@Column(name = "resume_id", updatable = false, nullable = false)
private UUID id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
private User user;
@NotNull(message = "First name may not be blank")
@Column(name = "first_name")
private String firstName;
@NotNull(message = "Last name may not be blank")
@Column(name = "last_name")
private String lastName;
@Column(name = "default")
private boolean isDefault;
@ElementCollection
@CollectionTable(
name = "resume_experience",
joinColumns = @JoinColumn(name = "resume_id")
)
private List<Experience> experiences;
...
Experience.java
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Experience implements Serializable
@Column(name = "current_job")
private boolean currentJob;
@NotNull
@Column(name = "start_date")
private Date startDate;
...
这是更新简历的方法。 ResumeService.java
public Resume updateResume(UUID resumeId, Resume resume) throws ResumeNotFoundException
Resume targetResume = resumeRepository.findById(resumeId).orElseGet(null);
if (targetResume != null)
resume.setId(targetResume.getId());
resume.setUser(targetResume.getUser());
resume.setCreatedAt(targetResume.getCreatedAt());
return resumeRepository.save(resume);
else
throw new ResumeNotFoundException("Resume not found");
错误信息
2020-02-12 00:23:20.113 ERROR 78958 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: syntax error at or near "default"
Position: 124
2020-02-12 00:23:20.182 ERROR 78958 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement] with root cause
org.postgresql.util.PSQLException: ERROR: syntax error at or near "default"
Position: 124
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2505) ~[postgresql-42.2.9.jar:42.2.9]
【问题讨论】:
@Column(name = "default") - 你确定吗?default
是关键字
default 是 SQL 中的关键字,请勿将其用作列名
【参考方案1】:
根据休眠documentation:
您可以强制 Hibernate 在生成的 SQL 中引用标识符,方法是在映射文档中将表或列名括在反引号中。传统上,Hibernate 使用反引号来转义 SQL 保留关键字,而 JPA 使用双引号。
因此,您可以通过这种方式更正您的映射:
@Column(name = "`default`")
private boolean isDefault;
或者这样:
@Column(name = "\"default\"")
private boolean isDefault;
【讨论】:
【参考方案2】:上面代码的问题是@Column(name = "default") 解决这个需要重命名“default”列名。我还用 mysql 数据库验证了相同的场景。
【讨论】:
以上是关于sql关键字作为jpa实体列名的用法的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL Server 存储过程中查找表名的列名作为保留关键字