使用SimpleJpaRepository#save(JpaRepository的默认实现,更新操作本质上是调用EntityManager#merge方法)进行更新操作时会发现:在传入的对象只有部分参数时,更新后数据库中该记录的其他字段为null

解决:

1
2
3
4
5
6
7
8
9
@Transactional
@Modifying
@Query("update User u set u.email=:#{#user.email} where u.id=:#{#user.id}")
void dynamicUpdateEmailById(@Param("user") User user);

@Transactional
@Modifying
@Query("update User u set u.email=?2 where u.id=?1")
void dynamicUpdateEmailById(int id, String email);

对于调用SimpJpaReposiory#sava插入新纪录后get不到id(主键)的问题

添加@GeneratedValue注解修改主键生成策略为GenerationType.IDENTITY,默认是GenerationType.AUTO
异常:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
解决:
使用GenerationType.IDENTITY

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Entity
@Table(name = "user")
public class User {
private int id;
private String username;
private String password;
private String email;

@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
...
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Entity
@Table(name = "user")
public class User {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
private String password;
private String email;

public int getId() {
return id;
}
...
}

注意:
测试将@GeneratedValue(strategy = GenerationType.IDENTITY)标注在属性(@Id@Column等还是标注于getter方法)时不生效,原因可能是PPB在解析属性和表字段映射时要么从getter方法进行解析绑定,要么从属性解析绑定,而不是解析属性和对应getter方法进行合并。