Java 使用hibernate进行Spring引导:创建复合键和多对多关系
我试图创建一个非常简单的Spring Boot应用程序来存储体育数据 它有两个实体:玩家和锦标赛。但是,我想存储每个球员在每个锦标赛中的排名 为此,我创建了下面的ER图。连接表Java 使用hibernate进行Spring引导:创建复合键和多对多关系,java,spring-boot,hibernate,orm,composite-key,Java,Spring Boot,Hibernate,Orm,Composite Key,我试图创建一个非常简单的Spring Boot应用程序来存储体育数据 它有两个实体:玩家和锦标赛。但是,我想存储每个球员在每个锦标赛中的排名 为此,我创建了下面的ER图。连接表PlayerPlacement\u map包含一个关系属性placement,用于存储玩家在锦标赛中的位置: 关于如何映射玩家和锦标赛之间的关系,我遵循了本指南,将这两个表中的Id作为名为PlayerPlacementMap的连接表中的复合键: 这给了我以下的课程: Player.java(Tournament.java
PlayerPlacement\u map
包含一个关系属性placement
,用于存储玩家在锦标赛中的位置:
关于如何映射玩家和锦标赛之间的关系,我遵循了本指南,将这两个表中的Id作为名为PlayerPlacementMap
的连接表中的复合键:
这给了我以下的课程:
Player.java(Tournament.java遵循类似的模式-为简洁起见省略)
PlayerPlacement.java(连接表)
我有关于球员、锦标赛和球员替换的存储库。玩家和锦标赛存储库本身运行良好,我能够通过@RestController对MSSQL数据库执行CRUD操作
这是playerplacement的存储库:
@Repository
public interface PlayerPlacementRepository extends JpaRepository<PlayerPlacement, PlayerPlacementKey>
{}
最后,问题来了:当我调用/“playerplacement”
端点时,我收到以下错误:
@RestController
public class PlayerPlacementController {
@Autowired
private PlayerPlacementRepository playerPlacementRepository;
@PostMapping("/playerplacement")
public PlayerPlacement addPlayerPlacement(@RequestBody PlayerPlacement playerPlacement) {
return playerPlacementRepository.save(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)
);
我还没有弄清楚我做错了什么。我感谢所有的帮助和指点,我收到-提前感谢
编辑:
在用户Alex V的帮助下取得了进展,但我现在遇到了一个新问题。
我进行以下JSON调用:
{
"player":
{
"name":"John Winther"
},
"tournament":
{
"name":"Spring Boot Cup 2020"
},
"placement":3
}
我自己没有设置id
(复合键)-我想应该由框架的某个部分来处理它?无论如何,当我在调试模式下进行此调用时,我会在端点中设置以下调试变量:
但是,它会导致以下错误:
@RestController
public class PlayerPlacementController {
@Autowired
private PlayerPlacementRepository playerPlacementRepository;
@PostMapping("/playerplacement")
public PlayerPlacement addPlayerPlacement(@RequestBody PlayerPlacement playerPlacement) {
return playerPlacementRepository.save(playerPlacement);
}
}
org.hibernate.id.IdentifierGenerationException: null id generated for:class com.testproject.learning.model.PlayerPlacement
java.lang.NullPointerException:无法调用“Object.getClass()”,因为“o”为null
,这可能是指PlayerPlacementKey.java
(?)中我的equals
-方法:
希望任何人都能再次将我推向正确的方向。您的实体有
playerId
字段,注释为@Column(name=“Player\u Id”)
,但数据库表包含playerId
列,而不是playerId
。与tournamentId
,player
,tournament
字段的情况相同
@MapsId(“TournamentId”)
必须包含@embeddedid
类字段名TournamentId
,而不是TournamentId
。这意味着该字段由嵌入的id字段映射tournamentId
@ManyToOne
@MapsId("tournamentId")
@JoinColumn(name = "tournamentId")
Tournament tournament;
这里也有同样的问题
@MapsId(“PlayerId”)
你好,alex,很抱歉反应太晚,我到现在还没找到。对于您答案的第一部分,我了解到,在每个名称为“锦标赛id”或“球员id”的列中,我将其更改为与数据库匹配,但不带下划线,例如“锦标赛id”?对于问题的第二部分,您的意思是我应该在PlayerPlacement.java中的锦标赛和玩家字段中添加@EmbeddedId(“tournamentId”)。在这种情况下,我有四个注释。而且,它给了我一个错误,当我这样做。我想知道你是否有任何文件可以参考或类似?谢谢。另外,在Player.java中,我定义了一个名为placements的@OneToMany
映射。我甚至需要这个,因为我已经在它上面做了一个@manytomy
地图吗?我已经在第二部分编辑了添加答案的示例。嗨,亚历克斯,再次感谢你回复我并添加更多信息。它把我推向了正确的方向!现在我能够正确地调用端点并设置一些变量。然而,我面临着一个新的问题:我在原来的帖子中添加了一个描述,从我添加了EDIT-tag的老帖子的底部开始。我希望你愿意再看一次。我非常感谢到目前为止的帮助,希望再次收到您的回复。您应该添加:if(null==o)return false
inequals
methodHey@alexvaluiskyi非常感谢。我试图将它添加到equals
-方法的第一行,但不幸的是,它返回了相同的错误消息。不过我真的很感谢你的帮助,非常感谢。据我所知,你试图将PlayerPlacement
包含Player
和锦标赛
保存到数据库中?如果是这样,您必须为每个关系添加一个适当的级联参数:。@alexvaluiskyi再次感谢Alex。我将仔细查看文档。我感谢你给我的所有帮助
@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;
}
@ManyToOne
@MapsId("tournamentId")
@JoinColumn(name = "tournamentId")
Tournament tournament;