【问题标题】:Spring Boot using save never inserts a row inside of a Postgresql tableSpring Boot 使用 save 永远不会在 Postgresql 表中插入一行
【发布时间】:2020-03-29 18:22:55
【问题描述】:
  1. 问题总结:

我无法在表格中保存新条目。在我决定尝试执行此任务之前,我遵循了一些教程,并且一切正常。我设法完美地完成了以下教程,同时还使用了 PostgreSQL https://www.callicoder.com/spring-boot-flyway-database-migration-example/

问题发生在我开始同时使用 WebController 和 RestController 时。使用 controller.save() 方法不会添加新行。 当我尝试运行它时,出现以下错误

ERROR: duplicate key value violates unique constraint "joke_pkey"
Detail: Key (id)=(1) already exists.

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session : [com.example.joke4u.Joke#1]; nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.example.joke4u.Joke#1]] with root cause
  1. 我的尝试:

在任何人说之前,我在某处读到,将两个控制器放在同一个应用程序中是不好的做法,但我必须这样做,因为这是我的任务要求我做的。 我试过四处研究,但我找不到其他人有同样的错误。 我什至尝试指定一个明显未使用但仅更新最后一行的 ID。

我尝试使用两者(obv 不是同时使用)

@GeneratedValue(strategy = GenerationType.TABLE)

@GeneratedValue(strategy = GenerationType.AUTO)

他们都不会改变结果

  1. 代码:

应用程序属性:

spring.datasource.url=jdbc:postgresql://localhost:5432/flyway_demo
spring.datasource.username=bob
spring.datasource.password=bob123

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

spring.jpa.hibernate.ddl-auto=create
spring.datasource.initialization-mode=always

我的具有 post 功能的 Web 控制器:

@PostMapping("/post")
public String insertJoke(JokeForm jokeForm) {
    int categoryid = jokeForm.getCategoryId();
    String content = jokeForm.getContent();
    databasController.insert(categoryid, content);
    return "redirect:/";
}

正在调用插入函数的我的 DBController"

public Joke insert(int categoryid, String content) {
    return jokeRepository.save(new Joke(categoryid, content));
}

Full Joke 数据类:

@Entity
public class Joke {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(columnDefinition = "serial")
private long id;

@NotNull
private int categoryid;

@NotBlank
private String content;

@Column(columnDefinition = "integer default 0")
private int likes = 0;

@Column(columnDefinition = "integer default 0")
private int dislikes = 0;

public Joke() {
}

public Joke(int categoryid, String content) {
    this.setCategoryid(categoryid);
    this.setContent(content);
}

public Joke(long id, int categoryid, String content) {
    this(categoryid, content);
    this.id = id;
}

//id
public long getId() {
    return this.id;
}

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

// categoryid
public int getCategoryid() {
    return this.categoryid;
}

public void setCategoryid(int categoryid) {
    this.categoryid = categoryid;
}

// content
public String getContent() {
    return this.content;
}

public void setContent(String content) {
    this.content = content;
}

// likes
public int getLikes() {
    return this.likes;
}

public void setLikes(int likes) {
    this.likes = likes;
}

public void incrementLikes() {
    ++likes;
}

public void decrementLikes() {
    --likes;
}

// dislikes
public int getDislikes() {
    return this.dislikes;
}

public void setDislikes(int dislikes) {
    this.dislikes = dislikes;
}

public void incrementDislikes() {
    ++dislikes;
}

public void decrementDislikes() {
    --dislikes;
}

@Override
public String toString() {
    return "{" + " id='" + getId() + "'" + ", categoryid='" + getCategoryid() + "'" + ", content='" + getContent()
            + "'" + ", likes='" + getLikes() + "'" + ", dislikes='" + getDislikes() + "'" + "}";
}}

笑话库:

@Repository
public interface JokeRepository extends JpaRepository<Joke, Integer> {
   Joke findById(long id);
   List<Joke> findByCategoryid(int categoryid);
}

编辑: 我发现了一些好消息!我可以在我的数据库中插入任意多的行,但前提是我不使用 data.sql 文件插入任何内容。这项任务需要我这样做:(

【问题讨论】:

  • 我相信这是问题GenerationType.TABLE尝试其他一些策略,例如GenerationType.AUTO
  • 对不起,我应该说我已经尝试过了。我最初在 GenerationType.AUTO 上使用它,但后来我发现有人遇到类似问题,有人建议改用 .TABLE。我只是试图把它放回自动,希望我现在真的解决了这个问题,但没有......即使使用自动它仍然是一样的。
  • Joke.id 不是自动生成的,而是显式设置(在您的控制器中)..显然是一个冲突的值...解决方案:a)清理数据库。 b) 选择另一个 ID(在您的表格中)。 c) 根本不设置 id(如果你想“测试”自动生成)。
  • 感谢您的想法。我尝试清洁我的基地几次。确实,我每次都从初始化数据库开始。但问题是,我从来没有为笑话设置 id。我的joke.id 怎么不是自动生成的,我只在控制器内部设置了它的内容和categoryid。
  • 您是否在 data.sql 插入中设置了 Joke.id,因为这是您搞砸的地方。您从 data.sql 插入的内容没有用完自动生成的 ID。

标签: java postgresql spring-boot spring-data-jpa


【解决方案1】:

我也遇到过类似情况。

我所做的是使用

@GeneratedValue(strategy = GenerationType.SEQUENCE

然后在我的 data.sql 文件中,我使用序列来添加数据。这会增加序列。

这是用于 postgreSQL 的:

INSERT INTO joke(id, categoryid, content )
VALUES (nextval('hibernate_sequence'), 1, 'joke');

【讨论】:

  • 嘿,别人帮了我。非常感谢您的回复。真正的答案是将其更改为 GenerationType.IDENTITY。我什至不需要添加 nextval('hibernate_sequence') 部分。
  • 好吧,我现在记得我为什么要使用用户序列。这是一种优化。你可以在这里阅读它thoughts-on-java.org/hibernate-postgresql-5-things-need-know
【解决方案2】:

有人帮我找到了答案。我非常感激。解决方案在这里。 Cannot use save() to insert when previously importing data using data.sql

如果你不想去那里只是想修复它。为我解决的只是将 GenerationType 更改为 AUTO 或 TABLE 或 SEQUENCE,而是更改为 IDENTITY。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-10
    • 2021-05-27
    • 1970-01-01
    • 2021-06-19
    • 2016-05-26
    • 1970-01-01
    • 2023-03-16
    • 2018-05-26
    相关资源
    最近更新 更多