我正在使用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
答案 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
}
}
在输入的用户名中,您可以先找到用户,然后在费用中设置用户对象,然后尝试保存它。