gpt4 book ai didi

Java JPA 外键引用未保存

转载 作者:行者123 更新时间:2023-11-30 05:35:26 25 4
gpt4 key购买 nike

我正在学习 SpringBoot 并尝试创建一个简单的 API。使用H2作为数据层。

我的表架构如下

DROP TABLE IF EXISTS Users;
DROP TABLE IF EXISTS Cards;
CREATE TABLE Users(USER_ID INT PRIMARY KEY,
NAME VARCHAR(255) NOT NULL,
USERNAME VARCHAR(255) NOT NULL,
PASSWORD VARCHAR(255) NOT NULL,
IS_ADMIN BOOL);

insert into Users values(10001,'Administrator', 'admin', 'admin', true);

CREATE TABLE Cards(CARD_ID INT PRIMARY KEY,
NUMBER VARCHAR(20) NOT NULL,
EXPIRY VARCHAR(5) NOT NULL,
CVV INT,
USER INT,
foreign key (USER) references Users(USER_ID)
);

我的信用卡实体如下所示。

package sprintboot;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
@Entity
@Table(name = "CARDS")
@ApiModel(description = "the Credit Card object")
public class CreditCard {

@ApiModelProperty(notes = "The DB ID of card")
private @Column(name = "CARD_ID") @Id @GeneratedValue Long card_id;

@NotBlank(message = "Credit card number is mandatory")
@ApiModelProperty(notes = "The number of credit card", required = true)
private @Column(name = "NUMBER") String number;

@NotBlank(message = "Credit card expiry is mandatory")
@ApiModelProperty(notes = "The expiry of credit card", required = true)
private @Column(name = "EXPIRY") String expiry;

@NotNull(message = "Credit card cvv is mandatory")
@ApiModelProperty(notes = "The cvv of credit card", required = true)
private @Column(name = "CVV") Integer cvv;

@ApiModelProperty(notes = "The owner user of credit card")
@ManyToOne
@JoinColumn
private User user;

public CreditCard() {}

public CreditCard(String number, String expiry, Integer cvv, User user) {
this.number = number;
this.expiry = expiry;
this.cvv = cvv;
this.user = user;
}

@Override
public String toString() {
return "{number: " + this.number + ", expiry: " + this.expiry + ", cvv: " + this.cvv + ", user: " + this.user + "}";
}
}

我的用户实体如下所示

package springboot;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.List;

@Data
@Entity
@Table(name = "USERS")
@ApiModel(description = "the USER object")
public class User {

@ApiModelProperty(notes = "The id of User")
private @Column(name = "USER_ID") @Id @GeneratedValue Long user_id;

@ApiModelProperty(notes = "The name of User")
private @Column(name = "NAME") String name;

@ApiModelProperty(notes = "The username of User", required = true)
@NotBlank(message = "Username is mandatory")
private @Column(name = "USERNAME") String username;

@ApiModelProperty(notes = "The password of User", required = true)
@ValidPassword(message = "Password is mandatory")
private @Column(name = "PASSWORD") String password;

@ApiModelProperty(notes = "The admin status of User")
private @Column(name = "IS_ADMIN") boolean isAdmin;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<CreditCard> cards;

public User() {}

public User(String name, String username, String password, boolean isAdmin) {
this.name = name;
this.username = username;
this.password = password;
this.isAdmin = isAdmin;
}

@Override
public String toString() {
return "{id: " + this.getUser_id() + ", username: " + this.getUsername() + ", isAdmin: " + this.isAdmin() + "}";
}
}

因此信用卡将包含一个用户。一个用户可以包含许多信用卡。我遇到的问题是当我尝试保存信用卡记录时。它抛出以下错误。

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.In
validDataAccessResourceUsageException: could not prepare statement; SQL [insert into cards (cvv, expiry, number, user_user_id, card_id) values (?, ?, ?, ?, ?)]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement] with root

原因

org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "USER_USER_ID" not found; SQL statement:
insert into cards (cvv, expiry, number, user_user_id, card_id) values (?, ?, ?, ?, ?) [42122-199]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:451) ~[h2-1.4.199.jar:1.4.199]

我尝试搜索并遵循几个教程,但无法使其正常工作。有人可以指出我错在哪里吗?

保存信用卡实体的方法如下。

public CreditCard upsertCC(
CreditCard card,
String jwtToken
) throws UnauthorizedException {
User user = this.getUserFromJWTToken(jwtToken);
log.info(user.toString());
card.setUser(user);
this.ccRepo.save(card);
this.ccRepo.flush();
card.setUser(null);
return card;
}

其中 getUserFromJWTToken 方法从 h2 表返回 User 对象。

任何建议

最佳答案

The exception actually is Column "USER_USER_ID" not found;

如果您看到查询,插入卡片(cvv、expiry、number、user_user_id、card_id)值(?, ?, ?, ?, ?), user_user_id 提到的不是列名

所以问题是您没有在 CreditCard 实体中将列名称提及为 user 。尝试下面的方法,它会起作用

要在 CreditCard.class 中进行的更改

    @ApiModelProperty(notes = "The owner user of credit card")
@ManyToOne
@JoinColumn(name = "user") // Added the name attribute
private User user;

如果你看一下@JoinColumn的name属性的源代码,他们已经清楚地提到了

  • If the join is for an element collection,
  • the join column name is formed as the
  • concatenation of the following: the name of the entity; "_";
  • the name of the referenced primary key column.

编辑

对于第二部分,您可以直接使用JPA的功能。

List<CreditCard> findByNumberContainingAndUser(String number, User user);

关于Java JPA 外键引用未保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56740309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com