PSQLException:错误:对表“ expenses”进行插入或更新违反了外键约束“ expenses_user_id_fkey”

时间:2018-10-27 18:05:43

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

我正在使用Kotlin和PostgreSql进行简单的Spring Boot服务。我使用JPA。目前我有两个表“ users”,“ expenses”,“ expenses”表引用了“ users” id:

CREATE TABLE users (
    id BIGINT NOT NULL PRIMARY KEY,
    username VARCHAR NOT NULL,
    password VARCHAR NOT NULL
);


CREATE TABLE expenses (
    id BIGINT NOT NULL PRIMARY KEY,
    user_id BIGINT NOT NULL REFERENCES users(id),
    price DECIMAL NOT NULL,
    title VARCHAR NOT NULL,
    description VARCHAR
);

实体看起来像这样:

@Entity
data class Users (
        @Id @GeneratedValue( strategy = GenerationType.AUTO ) val id: 
Long,
        val username: String,
        var password: String
) {
    @OneToMany
    val expenses: MutableSet<Expenses> = HashSet()
}

@Entity
data class Expenses(
        @Id @GeneratedValue( strategy = GenerationType.AUTO ) val id: 
Long? = null,
        val user_id: Long,
        val price: BigDecimal? = null,
        val title: String? = null,
        val description: String? = null
) {
    @ManyToOne
    lateinit var users: Users

    constructor(user_id: Long, users: Users) : this(user_id = user_id) {
        this.users = users
    }
}

我使用JPA存储库连接到数据库,并使用CrudRepository将数据插入数据库:

interface ExpensesRepository : CrudRepository<Expenses, Long> {
}

这里是我用于将数据插入db的代码:

@PostMapping("/expenses")
@ResponseBody
fun insertExpense(@RequestBody expenses: Expenses): Expenses {
    expensesRepository.save(expenses);
    return expenses;
}

然后用方法post发送到“ / expenses”的JSON:

{
    "user_id:": 43,
    "price": 10.99,
    "title": "C++ course",
    "description": "One time pay"
}

服务抛出PSQLException:

org.postgresql.util.PSQLException: ERROR: insert or update on table "expenses" violates foreign key constraint "expenses_user_id_fkey"
  Detail: Key (user_id)=(0) is not present in table "users".
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2477) ~[postgresql-42.1.4.jar:42.1.4]
...

在stackoverflow中有一些错误相同的答案,错误技术堆栈是不同的。

我用gradle。 Java版本:1.8 Kotlin版本:1.2.51 Spring Boot版本:2.0.6.RELEASE PostgreSQL版本:9.5.10 PostgreSql驱动程序版本:42.1.4

1 个答案:

答案 0 :(得分:0)

您应该在费用对象中设置用户对象。该关系似乎已中断,因为在输入Key(user_id)=(0)而不是(43)这是您输入的错误时出错。请尝试以下解决方案。 https://grokonez.com/spring-framework/spring-data/kotlin-springjpa-hibernate-one-many-relationship

@Entity
data class Users (
        @Id @GeneratedValue( strategy = GenerationType.AUTO ) val id: 
Long,
        val username: String,
        var password: String
) {
    @OneToMany
     @OneToMany(mappedBy = "users", cascade = arrayOf(CascadeType.ALL), fetch = FetchType.EAGER)
    val expenses: MutableSet<Expenses> = HashSet()
}

@Entity
data class Expenses(
        @Id @GeneratedValue( strategy = GenerationType.AUTO ) val id: 
Long? = null,
        val user_id: Long,
        val price: BigDecimal? = null,
        val title: String? = null,
        val description: String? = null
) {
    @ManyToOne
    lateinit var users: Users
    @JoinColumn(name = "user_id")
    constructor(user_id: Long, users: Users) : this(user_id = user_id) {
        this.users = users
    }
}

在输入的用户名中,您可以先找到用户,然后在费用中设置用户对象,然后尝试保存它。