Spring-Data JPARepository save method creates a duplicate Record
我正在使用spring-data和hibernate创建表并插入数据。 从不同的线程中,我发现JPARepository(来自CRUDRepository)的save方法仅在记录已存在的情况下才更新记录。 以下是我发现一些信息的线程之一:
https://stackoverflow.com/a/40608937/10356053
我有一个实体,它正在复制记录(即使对象相同,jpa也会考虑将其作为新插入)。 我不太确定发生了什么或该问题的解决方案。 任何建议表示赞赏。 以下是我创建的实体:
CustomerEntity.java:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Getter
@Setter
@Table (name ="Customers")
@ Entity
public class CustomersEntity extends BasicEntity {
@Id
@GeneratedValue (generator ="UUID")
@GenericGenerator (name ="UUID", strategy ="org.hibernate.id.UUIDGenerator")
@Column (name ="CustomerId", updatable = false, nullable = false)
private UUID customerid ;
//and some other fields
} |
BasicEntity.java:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Getter
@Setter
public class BasicEntity implements serializable {
@Temporal (TemporalType. TIMESTAMP)
@Column (name ="created_at", updatable = false)
@CreatedDate
private Date createdAt ;
@Temporal (TemporalType. TIMESTAMP)
@Column (name ="updated_at")
@LastModifiedDate
private Date updatedAt ;
} |
仓库.java
1 2 3 4 5
| @ Repository
public interface Repositorty extends JpaRepository <CustomersEntity, UUID > {
} |
当我们尝试保存上述实体时:
1
| repository.save(customerEntity) |
将作为新记录保留在数据库中。 任何建议都是有帮助的。 我在想这是由于父类的createdTime和updatedTime吗? 如果是,我们如何避免这种情况? TIA。
-
可能是由于每个记录UUID customerid;的新ID如果要更新记录,则具有相同的id
-
@Deadpool如果我的理解是正确的,jpa将在创建新的UUID之前检查是否相等?如果对象相同,应该更新记录而不是创建新记录?如果我错了,你能纠正我吗?
-
我不确定,但是您可以尝试使用现有的ID,看看它是否正在更新@ging
-
@Deadpool不只是在数据库中创建新行。
-
未设置createdTime的问题?因为我在您的计算机上尝试了您的代码,并且为给定的客户ID更新了同一行,就像@Deadpool已经说过的那样。
-
@Suraj否创建时间和更新时间正在更新..可能是覆盖了问题的equals方法吗?不确定..有什么想法吗?我忘了在帖子中提到我有一个自定义的重写equals方法,该方法基于customersEntity的几个属性,但是所有字段都是相同的。
将columnDefinition ="BINARY(16)"添加到customerid的@Column属性。
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Getter
@Setter
@Table (name ="Customers")
@ Entity
public class CustomersEntity extends BasicEntity {
@Id
@GeneratedValue (generator ="UUID")
@GenericGenerator (name ="UUID", strategy ="org.hibernate.id.UUIDGenerator")
@Column (name ="CustomerId", updatable = false, nullable = false, columnDefinition ="BINARY(16)")
private UUID customerid ;
//and some other fields
} |
没有它,customer_id列将使用256个字节(在MySQL中),这很可能导致UUID公式在随后保存相同实体对象(解释重复创建)时失败。
详细信息:休眠和UUID标识符
-
感谢您的回应。我尝试添加更改。但是我仍然可以看到添加了两行。而且我们使用的是sql server,而不是MySql。抱歉,没有在帖子中提及。有什么想法吗?
-
@ging您是否尝试删除并重新创建表(如果可以的话)?
-
是。我确实放下了表并再次创建了表。但是没有运气@MartinBG
-
@gingers当customers_id列设置为binary(16)时,我无法在MySQL上重新创建问题。到那时,我将尝试尽可能简化设置-用一个简单的实体(没有继承,只有一个id,默认等于和hashCode方法)进行测试,尝试使用Long类型的id,也许可以在一个新的对象中进行所有操作项目以限制噪音。我有一个简单的项目,如果您想在那里进行测试,可以将其上传到github。
-
尝试了大多数事情。通过重新创建表,尝试使用longId进行操作,没有继承,并且默认情况下等于equals和哈希码。但没有运气,但仍然可以看到正在创建两行:((您要我尝试的任何其他想法或建议吗?任何其他的一对多或多对多关系可能在这里产生影响?@MartinBG
-
@ging您可以确认使用columnDefinition ="BINARY(16)"创建的表中的customer_id列的类型是binary(16)吗?
-
@ging从以下问题中我所阅读的内容可能是Hibernate + SQL Server问题:stackoverflow.com/questions/42559938/ stackoverflow.com/questions/41651681/