我正在使用 Spring boot 和 Mysql。每当我从 CrudRepository 调用 save 方法时,它都会替换表中的实体。我希望它将新实体合并到表中现有实体中。
我在这里做错了什么?
例如。数据库中的条目:id=12345,firstName=foo,lastName=bar使用新实体调用保存:id=12345,firstName=doe
保存操作后,db有,id=12345,firstName=doe,lastName=null
我的实体类:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
public class Branch {
@Id
@Column(name = "id")
private String id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
@Column(name = "latitude")
private String latitude;
@Column(name = "longitude")
private String longitude;
@Column(name = "email")
private String email;
@Column(name = "phone")
private String phone;
@Enumerated(EnumType.STRING)
private BranchType branchType;
}
我的仓库:
public interface BranchRepo extends CrudRepository<Branch, String> {
}
应用程序属性
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://mysql-url
spring.datasource.username=user-name-here
spring.datasource.password=password-name-here
spring.jpa.show-sql = true
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.DefaultNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.type=trace
最佳答案
主要关心的是不要强制开发人员通过调用 findOne() 然后合并两个对象然后调用 save() 来显式处理更新操作。
由于 Spring Data 不支持开箱即用,我需要将此功能添加到我们的 API 平台。
首先,我尝试扩展 JpaRepository 的行为来覆盖 save() 方法。但作为一个界面,我无法更新此行为。
我最终创建了一个 EntityMergingService,它接受两个实体,一个来自数据库,一个来自内存。然后它使用反射来进行空检查并进行合并。
调用方有责任调用 findOne(),从上述服务中调用 merge,然后调用 save()。
这样,我们就不必为每个实体编写多个合并方法。这不是最好的方法,如果我可以重写 JPA 存储库中的 save() 方法,那就更好了。这将在内部执行 findOne() 以及合并和保存合并对象。
关于hibernate - Spring boot CrudRepo Save() 方法不会合并现有条目,但会替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45435271/