【发布时间】:2022-01-25 05:52:10
【问题描述】:
自从从 Spring Boot 2.2.x 升级到 2.6.x(以及 Java 11 -> 17)后,我们的实体类在某些存储库方法方面存在问题。我们使用 UUID 作为我们的数据库 id,但在域层中也有强类型的 id 以保证类型安全。 DB 是 Postgres。
示例(带有一些额外的注释,并不能解决问题):
@Entity
@Access(AccessType.FIELD)
public class User {
@Id private UUID id;
@Transient
public UserId id() {
return new UserId(id);
}
}
我们的存储库类:
public interface UserJPARepository extends CrudRepository<User, UUID> { }
以下失败:
repository.deleteById(userId.id());
有错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Provided id of the wrong type for class com.example.User. Expected: class java.util.UUID, got class com.example.CycleId; nested exception is java.lang.IllegalArgumentException: Provided id of the wrong type for class com.example..Cycle. Expected: class java.util.UUID, got class com.example.CycleId
问题似乎是 JPA 正在使用反射来确定 public UserId id() 是 Id 的正确 getter,但是由于此方法将 UUID 转换为 UserId,因此它失败了。重命名 id() 方法可以解决问题,但这并不理想。
在我的id() 方法中添加断点,我可以看到调用来自JpaMetamodalEntityInformation.getId:
if (idMetadata.hasSimpleId()) {
return (ID) entityWrapper.getPropertyValue(idMetadata.getSimpleIdAttribute().getName());
}
Transient 和 Access 注释无助于解决问题。
在 Spring Boot 2.2 中一切正常。升级引入了这个问题。
【问题讨论】:
标签: java spring-boot hibernate spring-data-jpa java-17