添加到集合会创建记录,但不会 link 它到父级
Adding to collection creates record, but does not link it to parent
我有两个非常简单的实体:
@Entity
public class CanonUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String crm;
private String name;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Address> address;
// getters and setters omitted
}
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String city;
private String street;
@ManyToOne
private CanonUser user;
// getters and setters omitted
}
和一个基本存储库:
@RepositoryRestResource(path = "users", collectionResourceRel = "users", itemResourceRel = "user")
public interface CanonUserRepo extends CrudRepository<CanonUser, Long> {
}
我正尝试通过此请求将项目添加到地址:
curl 'http://localhost:8080/companion-backend/api/users/3' -i -X PATCH \
-H 'Accept: application/hal+json' \
-H 'Content-Type: application/json-patch+json; charset=ISO-8859-1' \
-d '[{"op":"add", "path":"/address/-","value":{"city":"Jim", "street":"Jim Grove"}}]'
这会创建地址记录但不会link它给用户:
2018-03-13 11:05:04.242 DEBUG 18533 --- [nio-8080-exec-1] jdbc.sqltiming : com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
1. select canonuser0_.id as id1_1_0_, canonuser0_.crm as crm2_1_0_, canonuser0_.name as name3_1_0_, address1_.user_id as user_id4_0_1_, address1_.id as id1_0_1_, address1_.id as id1_0_2_,
address1_.city as city2_0_2_, address1_.street as street3_0_2_, address1_.user_id as user_id4_0_2_ from canon_user canonuser0_ left outer join address address1_ on canonuser0_.id=address1_.user_id
where canonuser0_.id=3
{executed in 0 msec}
2018-03-13 11:05:04.353 DEBUG 18533 --- [nio-8080-exec-1] jdbc.sqltiming : com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
1. insert into address (id, city, street, user_id) values (null, 'Jim', 'Jim Grove', NULL)
{executed in 2 msec}
2018-03-13 11:05:04.355 DEBUG 18533 --- [nio-8080-exec-1] jdbc.sqltiming : com.zaxxer.hikari.pool.ProxyStatement.getGeneratedKeys(ProxyStatement.java:230)
1. getGeneratedKeys on query: insert into address (id, city, street, user_id) values (null, 'Jim', 'Jim Grove', NULL)
{executed in 2 msec}
我做错了什么?
<spring.version>5.0.4.RELEASE</spring.version>
<spring-data-releasetrain.version>Kay-SR4</spring-data-releasetrain.version>
正如我在评论中所说,Spring 数据作者解释了为什么双向 one-to-many 在 SDR 中不起作用你可以找到 .
但是您可以使用折衷变体来避免第 3 次,连接 one-to-many 中的 table 与 @JoinColumn
注释组合的关联:
@Data
@Entity
public class Parent implements Serializable {
@Id @GeneratedValue private Integer id;
private String name;
@OneToMany(cascade = ALL, orphanRemoval = true)
@JoinColumn(name = "parent_id", foreignKey = @ForeignKey(name = "fk_children_parent"))
private List<Child> children;
}
@Data
@Entity
public class Child implements Serializable {
@Id @GeneratedValue private Integer id;
private String name;
}
public interface ParentRepo extends JpaRepository<Parent, Integer> {
}
在这种情况下,您只会得到两个 table:
CREATE TABLE PARENT
(
ID integer PRIMARY KEY NOT NULL,
NAME varchar(255)
)
CREATE TABLE CHILD
(
ID integer PRIMARY KEY NOT NULL,
NAME varchar(255),
PARENT_ID integer,
CONSTRAINT FK_CHILDREN_PARENT FOREIGN KEY (PARENT_ID) REFERENCES PARENT (ID)
);
我写'compromise variant'是因为这种组合产生了过多的查询,compared是双向的。例如,创建一个 parent 和两个 children 会产生五个查询:
POST http://localhost:8080/parents
{
"name": "parent1",
"children": [
{
"name": "child1"
},
{
"name": "child2"
}
]
}
insert into parent (name, id) values ('parent1', 1)
insert into child (name, id) values ('child1', 2)
insert into child (name, id) values ('child2', 3)
update child set parent_id=1 where id=2
update child set parent_id=1 where id=3
用一个 child 更新此 parent 产生以下查询序列:
PATCH http://localhost:8080/parents/1
{
"name": "parent1",
"children": [
{
"name": "child3"
}
]
}
select c.parent_id, c.id, c.name from child c where c.parent_id=1
update child set name='child3' where id=2
update child set parent_id=null where parent_id=1 and id=3
delete from child where id=3
我有两个非常简单的实体:
@Entity
public class CanonUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String crm;
private String name;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Address> address;
// getters and setters omitted
}
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String city;
private String street;
@ManyToOne
private CanonUser user;
// getters and setters omitted
}
和一个基本存储库:
@RepositoryRestResource(path = "users", collectionResourceRel = "users", itemResourceRel = "user")
public interface CanonUserRepo extends CrudRepository<CanonUser, Long> {
}
我正尝试通过此请求将项目添加到地址:
curl 'http://localhost:8080/companion-backend/api/users/3' -i -X PATCH \
-H 'Accept: application/hal+json' \
-H 'Content-Type: application/json-patch+json; charset=ISO-8859-1' \
-d '[{"op":"add", "path":"/address/-","value":{"city":"Jim", "street":"Jim Grove"}}]'
这会创建地址记录但不会link它给用户:
2018-03-13 11:05:04.242 DEBUG 18533 --- [nio-8080-exec-1] jdbc.sqltiming : com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
1. select canonuser0_.id as id1_1_0_, canonuser0_.crm as crm2_1_0_, canonuser0_.name as name3_1_0_, address1_.user_id as user_id4_0_1_, address1_.id as id1_0_1_, address1_.id as id1_0_2_,
address1_.city as city2_0_2_, address1_.street as street3_0_2_, address1_.user_id as user_id4_0_2_ from canon_user canonuser0_ left outer join address address1_ on canonuser0_.id=address1_.user_id
where canonuser0_.id=3
{executed in 0 msec}
2018-03-13 11:05:04.353 DEBUG 18533 --- [nio-8080-exec-1] jdbc.sqltiming : com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
1. insert into address (id, city, street, user_id) values (null, 'Jim', 'Jim Grove', NULL)
{executed in 2 msec}
2018-03-13 11:05:04.355 DEBUG 18533 --- [nio-8080-exec-1] jdbc.sqltiming : com.zaxxer.hikari.pool.ProxyStatement.getGeneratedKeys(ProxyStatement.java:230)
1. getGeneratedKeys on query: insert into address (id, city, street, user_id) values (null, 'Jim', 'Jim Grove', NULL)
{executed in 2 msec}
我做错了什么?
<spring.version>5.0.4.RELEASE</spring.version>
<spring-data-releasetrain.version>Kay-SR4</spring-data-releasetrain.version>
正如我在评论中所说,Spring 数据作者解释了为什么双向 one-to-many 在 SDR 中不起作用你可以找到
但是您可以使用折衷变体来避免第 3 次,连接 one-to-many 中的 table 与 @JoinColumn
注释组合的关联:
@Data
@Entity
public class Parent implements Serializable {
@Id @GeneratedValue private Integer id;
private String name;
@OneToMany(cascade = ALL, orphanRemoval = true)
@JoinColumn(name = "parent_id", foreignKey = @ForeignKey(name = "fk_children_parent"))
private List<Child> children;
}
@Data
@Entity
public class Child implements Serializable {
@Id @GeneratedValue private Integer id;
private String name;
}
public interface ParentRepo extends JpaRepository<Parent, Integer> {
}
在这种情况下,您只会得到两个 table:
CREATE TABLE PARENT
(
ID integer PRIMARY KEY NOT NULL,
NAME varchar(255)
)
CREATE TABLE CHILD
(
ID integer PRIMARY KEY NOT NULL,
NAME varchar(255),
PARENT_ID integer,
CONSTRAINT FK_CHILDREN_PARENT FOREIGN KEY (PARENT_ID) REFERENCES PARENT (ID)
);
我写'compromise variant'是因为这种组合产生了过多的查询,compared是双向的。例如,创建一个 parent 和两个 children 会产生五个查询:
POST http://localhost:8080/parents
{
"name": "parent1",
"children": [
{
"name": "child1"
},
{
"name": "child2"
}
]
}
insert into parent (name, id) values ('parent1', 1)
insert into child (name, id) values ('child1', 2)
insert into child (name, id) values ('child2', 3)
update child set parent_id=1 where id=2
update child set parent_id=1 where id=3
用一个 child 更新此 parent 产生以下查询序列:
PATCH http://localhost:8080/parents/1
{
"name": "parent1",
"children": [
{
"name": "child3"
}
]
}
select c.parent_id, c.id, c.name from child c where c.parent_id=1
update child set name='child3' where id=2
update child set parent_id=null where parent_id=1 and id=3
delete from child where id=3