我试图创建一个非常简单的spring-boot应用程序来存储运动数据。
它有两个实体:玩家和锦标赛。但是,我想存储每个球员在每个锦标赛中的位置。
为此,我创建了下面的er图。连接表 PlayerPlacement_map
包含关系属性 placement
用于存储玩家在锦标赛中的位置:
我遵循了这个指南,了解了如何Map玩家和锦标赛之间的关系,将这两个表中的id作为连接表中名为 PlayerPlacementMap
: https://www.baeldung.com/jpa-many-to-many
这给了我以下的课程:
player.java(tournament.java遵循类似的模式-为简洁起见,请省略)
@Entity
@Table(name = "players")
public class Player {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id", updatable = false, nullable = false)
private long id;
@Column(name = "Name")
private String name;
@ManyToMany
@JoinTable(
name = "PlayerTournament_map",
joinColumns = @JoinColumn(name = "Player_Id"),
inverseJoinColumns = @JoinColumn(name = "Tournament_Id"))
Set<Tournament> attendedTournaments;
@OneToMany(mappedBy = "player")
Set<PlayerPlacement> placements;
//getters, constructors - left out for brevity
}
playerplacementkey.java(生成可嵌入的复合键类)
@Embeddable
public class PlayerPlacementKey implements Serializable {
@Column(name = "Player_Id")
long playerId;
@Column(name = "Tournament_Id")
long tournamentId;
//getters, setters, constructors, equals, hashcode - left out for brevity
}
playerplacement.java(连接表)
@Entity
@Table(name = "PlayerPlacement_map")
public class PlayerPlacement {
@EmbeddedId
PlayerPlacementKey id;
@ManyToOne
@MapsId("PlayerId")
@JoinColumn(name = "Player_Id")
Player player;
@ManyToOne
@MapsId("TournamentId")
@JoinColumn(name = "Tournament_Id")
Tournament tournament;
int placement;
//constructors - left out for brevity
}
我有球员,锦标赛和球员位置库。玩家和锦标赛存储库本身运行良好,我可以通过@restcontroller对mssql数据库执行crud操作。
这是playerplacement的存储库:
@Repository
public interface PlayerPlacementRepository extends JpaRepository<PlayerPlacement, PlayerPlacementKey>
{}
对于连接表,我制作了一个playerplacementcontroller:
@RestController
public class PlayerPlacementController {
@Autowired
private PlayerPlacementRepository playerPlacementRepository;
@PostMapping("/playerplacement")
public PlayerPlacement addPlayerPlacement(@RequestBody PlayerPlacement playerPlacement) {
return playerPlacementRepository.save(playerPlacement);
}
}
最后,问题来了:当我打电话给 /"playerplacement"
端点,我收到以下错误:
org.hibernate.id.IdentifierGenerationException: null id generated for:class com.testproject.learning.model.PlayerPlacement
我想我已经很好地迁移了数据库,但为了安全起见,下面是我对连接表的迁移:
CREATE TABLE PlayerPlacement_map (
PlayerId Bigint NOT NULL,
TournamentId Bigint NOT NULL,
Placement int
CONSTRAINT PK_PlayerPlacement NOT NULL IDENTITY(1,1) PRIMARY KEY
(
PlayerId,
TournamentId
)
FOREIGN KEY (PlayerId) REFERENCES Players (Id),
FOREIGN KEY (TournamentId) REFERENCES Tournaments (Id)
);
我还没弄清楚我做错了什么。我感谢所有的帮助和指点,我收到-提前感谢。
编辑:在用户alexv的帮助下已经取得了进展,但是我现在遇到了一个新问题。
我进行以下json调用:
{
"player":
{
"name":"John Winther"
},
"tournament":
{
"name":"Spring Boot Cup 2020"
},
"placement":3
}
我不设定 id
(复合键)我自己-我想应该由框架的某个部分来处理?无论如何,当我在调试模式下进行此调用时,会在端点中设置以下调试变量:
但是,它会导致以下错误: java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "o" is null
,可能是指我的 equals
-中的方法 PlayerPlacementKey.java
(?):
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PlayerPlacementKey)) return false;
PlayerPlacementKey that = (PlayerPlacementKey) o;
return playerId == that.playerId &&
tournamentId == that.tournamentId;
}
希望有人能再把我推向正确的方向。
1条答案
按热度按时间yhxst69z1#
您的实体
playerId
字段注解为@Column(name = "Player_Id")
,但数据库表包含PlayerId
列而不是Player_Id
. 同样的情况tournamentId
,player
,tournament
领域。@MapsId("TournamentId")
必须包含@EmbededId
类字段名tournamentId
而不是TournamentId
. 这意味着该字段由嵌入的id字段MaptournamentId
.同样的问题
@MapsId("PlayerId")
.