JPA不将属性保存在MYSQL数据库中



我现在正在学习Spring引导,我将其用作后端,并将React用作前端。

我正在通过JPA-Hibernate保存数据,每个属性都得到了正确的保存,但team_name没有得到保存,我不知道为什么没有保存,我希望你能帮助我。

我的MySQL表播放器有4个属性:id是主键、年龄、姓名、团队名称作为外键

然后MySQL表Team有一个属性名称,它是主键。正如您在Java代码播放器中看到的那样,播放器和团队是一种关系。

当我可以记录this.state.team属性时,它会给我团队名称,它不是null,只是不会保存在MySQL表中。

更新代码:

Java播放器实体:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Player {
@Id
private String id;

private String name;
private String age;
@ManyToOne 
@JsonBackReference
private Team team;

}

Java团队实体:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Team {
@Id
private String name;
@JsonManagedReference
@OneToMany(mappedBy = "team")
private List<Player> players;
}

反应代码:

class Player extends Component {
constructor(){
super();
this.state={
player:{},
playerName: null,
id:null,
flag:null,
age:null,
team:null,
name: null
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.getPlayerData = this.getPlayerData.bind(this)
}
async getPlayerData(playerName){
const proxyurl = "https://cors-anywhere.herokuapp.com/";    
const url = "https://www.hltv.org/search?term=" + playerName
const fullUrl= proxyurl+url
const response = await fetch(fullUrl)
const arr = await response.json()
const player = arr[0].players[0];
const fullName= player.firstName + " " + player.lastName

this.setState({
playerName: player.nickName,
id: player.id,
flag: player.flagUrl,
age:null,
team:{
name: player.team.name
},
name: fullName
})
}
async createNonExistingTeam(){
const teamData={
name:this.state.team.name
}
await fetch("/api/team" , {
method: 'POST' ,
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify(teamData)
})
}
async createNonExistingPlayer(){
const data={
id: this.state.playerName,
age: null,
name:this.state.name,
team_name: this.state.team.name
}
await fetch("/api/player" , {
method: 'POST' ,
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify(data)
})
await this.handleSubmit()
}

async handleSubmit(event){
const {playerName} = this.state

try{
const response =  await fetch(`/api/player/${playerName}` , {
method: 'GET' ,
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
}})
const output = await response.json();
this.setState({
player:output
})
} catch(e){
await this.getPlayerData(playerName)
await this.createNonExistingTeam()
await this.createNonExistingPlayer()
}
const style = {
marginTop: 20,
marginLeft: 30
}
const {player} = this.state
const {playerData} = this.state
const {flag} = this.state
const {id} = this.state

const picLink = "https://static.hltv.org//images/playerprofile/bodyshot/compressed/" + id + ".png"
const data = 
<div>
<PlayerData
style={style} 
ign={player.id}
name={player.name} 
pic={picLink}
nation={flag}
age={player.age}
/>
</div>

ReactDOM.render(data,document.getElementById('playerData'))

}


async handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}

编辑控制器代码:

播放器控制器:

@RestController
@RequestMapping("/api")
public class PlayerController {
@Autowired
private PlayerRepository playerRepository;
@GetMapping("/players")
List<Player>getAllPlayers(){
return playerRepository.findAll();
}
@PostMapping("/player")
ResponseEntity<Player> createPlayer(@Valid @RequestBody Player player) throws URISyntaxException{
Player result = playerRepository.save(player);
return ResponseEntity.created(new URI("/api/player" + result.getId())).body(player);
}
@GetMapping("/player/{id}")
ResponseEntity<?> getPlayer(@PathVariable String id){
Optional<Player>result =  playerRepository.findById(id);
ResponseEntity<Player> resMap = result.map(response->ResponseEntity.ok().body(response)).orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
return resMap;
}
@GetMapping("/{name}/players")
List<Player> findPlayers(@PathVariable Team name){
return playerRepository.findByTeam(name);
}
}

TeamController:

@RestController
@RequestMapping("/api")
public class TeamController {
@Autowired
private TeamRepository tRepository;
@PostMapping("/team")
ResponseEntity<Team> createTeam(@Valid @RequestBody Team team) throws URISyntaxException{
Team result = tRepository.save(team);
return ResponseEntity.created(new URI("/api/team/" + result.getName())).body(team);
}

}

编辑:

我意识到,当我在Java中的create player方法中打印我的播放器时,团队显示为NULL,所以我想我的POST请求有问题。

您的映射不正确,您可以删除@Table注释,因为这是冗余的

您也不应该使用@Data注释,因为这可能会导致双向引用的StackOverflowError。

首先使用@ManyToOne而不是@OneToOne:

@Entity
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
public class Player {
@Id
private String id;
private String name;
private String age;
@ManyToOne 
@JsonBackReference
private Team team;
}

然后您必须使用mappedBy属性来告诉JPA有一个反向引用:

@Entity
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name="team")
public class Team {
@Id
private String name;
@JsonManagedReference
@OneToMany(mappedBy = "team")
private List<Player> players;
}

您的前端Player组件不表示PlayerTeam实体关系。

应该是:

{
playerName: player.nickName,
id: player.id,
flag: player.flagUrl,
age:null,
team:{
name:player.team.name
},
name: fullName
}

我解决了我的问题。我发现我的POST请求中有一个错误。我将getPlayerData方法更改为:

this.setState({
playerName: player.nickName,
id: player.id,
flag: player.flagUrl,
age:null,
team:{
name: player.team.name
},
name: fullName
})

在POST请求中,我创建了一个新变量。

const dat={
name: this.state.team.name
}    

并更改了我的数据对象如下:

const data={
id: this.state.playerName,
age: null,
name:this.state.name,
team: dat
}

最新更新