Spring 数据 JDBC:未找到 MappedCollection 所需的标识符 属性
Spring Data JDBC: Required identifier property not found for a MappedCollection
class Game(
@MappedCollection(idColumn = "game") <---- unnecessary
var rules: List<Rule> = emptyList(),
){
@Id
var id: Long? = null
}
data class Rule(
@MappedCollection(idColumn = "rule", keyColumn = "rule_key")<---- unnecessary
val ruleValues: List<RuleValue>
)
data class RuleValue(val value: String)
架构是
create table game
(
id serial primary key
);
create table rule
(
id serial primary key,
game long references game (id),
game_key integer
);
create table rule_value
(
id serial primary key,
game long references game (id),
game_key integer,
rule long references rule (id),
rule_key integer,
value varchar(256)
);
简而言之,我有一个 Game
作为根聚合。 game
有一个 Rules
的列表(顺序很重要),rule
有一个 rule values
的列表(顺序很重要)。 rule value
目前只是一个字符串,但将来可能会扩展。
我有两个问题:
1) 未找到所需的标识符 属性:当我尝试保存游戏时,我收到 Caused by: java.lang.IllegalStateException: Required identifier property not found for class com...RuleValue!
异常消息。
2) java.sql.SQLSyntaxErrorException :为什么 rule_value
[=77= 中需要 game
和 game_key
列]?如果我不放它们,我会得到 Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'game_key' in 'field list'
我正在使用 Spring 引导版本 2.2。5.RELEASE 与 org.springframework.boot:spring-boot-starter-data-jdbc
对应于 spring-data-jdbc
版本 1.1。5.RELEASE
SOLUTION-1:将 ID 字段添加到 class
正如@chrylis-onstrike- 建议的那样,我在所有数据中添加了 @Id
字段 classes
class Game(
@MappedCollection(idColumn = "game")
var rules: List<Rule> = emptyList(),
){
@Id
var id: Long? = null
}
data class Rule(
@MappedCollection(idColumn = "rule", keyColumn = "rule_key")
val ruleValues: List<RuleValue>
) {
@Id
var id: Long? = null <---- this is new
}
data class RuleValue(val value: String) {
@Id
var id: Long? = null <---- this is new
}
架构更改为
create table game
(
id serial primary key
);
create table rule
(
id serial primary key,
game long references game (id),
game_key integer
);
create table rule_value
(
id serial primary key,
# game long references game (id), <---- removed this
# game_key integer, <---- removed this
rule long references rule (id),
rule_key integer,
value varchar(256)
);
SOLUTION-2:将复合主键添加到脚本中
class Game(
@MappedCollection(idColumn = "game")
var rules: List<Rule> = emptyList(),
){
@Id
var id: Long? = null
}
data class Rule(
@MappedCollection(idColumn = "rule", keyColumn = "rule_key")
val ruleValues: List<RuleValue>
)
data class RuleValue(val value: String)
架构更改为
create table game
(
id serial primary key
);
create table rule
(
# id serial primary key, <---- removed
game integer,
game_key integer,
primary key (game, game_key) <---- added
);
create table rule_value
(
# id serial primary key, <---- removed
game integer, <---- added
game_key integer, <---- added
rule_key integer,
value varchar(2048),
primary key (game, game_key, rule_key) <---- added
);
结论
您需要决定您的对象是 value object
还是一个实体。一个值对象可能不应该在 class 中有一个 id 字段,因为它的身份是由它携带的值定义的。但是,您需要在数据库 table 中识别一行并将其与它的所有者相关联,因此如果您希望将它们保存在不同的 tables 上,则需要在值对象中创建复合主键。
未找到所需的标识符 属性。
我同意@chrylis-onstrike-错误告诉您添加一个带有 @Id
注释的字段。
但我也同意你的看法:情况不应该如此。
我至少需要一个完整的堆栈跟踪来了解发生了什么。
复制器会更好。
欢迎在 https://jira.spring.io/browse/DATAJDBC
上创建问题
对提供的复制器的进一步调查表明问题是由 id
列仍然存在于数据库中并且是 identity
列引起的。
因此 JDBC 在插入后执行 return 一个值,并且 Spring Data JDBC 尝试将其设置为实体上的 id,然后未能设置该 id 并出现异常在问题中。
为什么我需要 rule_value
table 中的游戏和 game_key
列?
只要 Rule
没有专用 ID,其主键就是 game
和 game_key
的组合,因此来自 rule_value
的引用由以下组成这两个字段。
当 Rule
有 id 时,它们不应该是必需的。
class Game(
@MappedCollection(idColumn = "game") <---- unnecessary
var rules: List<Rule> = emptyList(),
){
@Id
var id: Long? = null
}
data class Rule(
@MappedCollection(idColumn = "rule", keyColumn = "rule_key")<---- unnecessary
val ruleValues: List<RuleValue>
)
data class RuleValue(val value: String)
架构是
create table game
(
id serial primary key
);
create table rule
(
id serial primary key,
game long references game (id),
game_key integer
);
create table rule_value
(
id serial primary key,
game long references game (id),
game_key integer,
rule long references rule (id),
rule_key integer,
value varchar(256)
);
简而言之,我有一个 Game
作为根聚合。 game
有一个 Rules
的列表(顺序很重要),rule
有一个 rule values
的列表(顺序很重要)。 rule value
目前只是一个字符串,但将来可能会扩展。
我有两个问题:
1) 未找到所需的标识符 属性:当我尝试保存游戏时,我收到 Caused by: java.lang.IllegalStateException: Required identifier property not found for class com...RuleValue!
异常消息。
2) java.sql.SQLSyntaxErrorException :为什么 rule_value
[=77= 中需要 game
和 game_key
列]?如果我不放它们,我会得到 Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'game_key' in 'field list'
我正在使用 Spring 引导版本 2.2。5.RELEASE 与 org.springframework.boot:spring-boot-starter-data-jdbc
对应于 spring-data-jdbc
版本 1.1。5.RELEASE
SOLUTION-1:将 ID 字段添加到 class
正如@chrylis-onstrike- 建议的那样,我在所有数据中添加了 @Id
字段 classes
class Game(
@MappedCollection(idColumn = "game")
var rules: List<Rule> = emptyList(),
){
@Id
var id: Long? = null
}
data class Rule(
@MappedCollection(idColumn = "rule", keyColumn = "rule_key")
val ruleValues: List<RuleValue>
) {
@Id
var id: Long? = null <---- this is new
}
data class RuleValue(val value: String) {
@Id
var id: Long? = null <---- this is new
}
架构更改为
create table game
(
id serial primary key
);
create table rule
(
id serial primary key,
game long references game (id),
game_key integer
);
create table rule_value
(
id serial primary key,
# game long references game (id), <---- removed this
# game_key integer, <---- removed this
rule long references rule (id),
rule_key integer,
value varchar(256)
);
SOLUTION-2:将复合主键添加到脚本中
class Game(
@MappedCollection(idColumn = "game")
var rules: List<Rule> = emptyList(),
){
@Id
var id: Long? = null
}
data class Rule(
@MappedCollection(idColumn = "rule", keyColumn = "rule_key")
val ruleValues: List<RuleValue>
)
data class RuleValue(val value: String)
架构更改为
create table game
(
id serial primary key
);
create table rule
(
# id serial primary key, <---- removed
game integer,
game_key integer,
primary key (game, game_key) <---- added
);
create table rule_value
(
# id serial primary key, <---- removed
game integer, <---- added
game_key integer, <---- added
rule_key integer,
value varchar(2048),
primary key (game, game_key, rule_key) <---- added
);
结论
您需要决定您的对象是 value object
还是一个实体。一个值对象可能不应该在 class 中有一个 id 字段,因为它的身份是由它携带的值定义的。但是,您需要在数据库 table 中识别一行并将其与它的所有者相关联,因此如果您希望将它们保存在不同的 tables 上,则需要在值对象中创建复合主键。
未找到所需的标识符 属性。
我同意@chrylis-onstrike-错误告诉您添加一个带有
上创建问题@Id
注释的字段。 但我也同意你的看法:情况不应该如此。 我至少需要一个完整的堆栈跟踪来了解发生了什么。 复制器会更好。 欢迎在 https://jira.spring.io/browse/DATAJDBC对提供的复制器的进一步调查表明问题是由
id
列仍然存在于数据库中并且是identity
列引起的。 因此 JDBC 在插入后执行 return 一个值,并且 Spring Data JDBC 尝试将其设置为实体上的 id,然后未能设置该 id 并出现异常在问题中。为什么我需要
rule_value
table 中的游戏和game_key
列?只要
Rule
没有专用 ID,其主键就是game
和game_key
的组合,因此来自rule_value
的引用由以下组成这两个字段。当
Rule
有 id 时,它们不应该是必需的。