語境
當我的服務呼叫時repository.delete(myEntity),我收到以下錯誤:
105 | 您為此查找操作提供了不正確的 PK 類的實體。 預期類:com.foo.PrimaryKey 類,接收到的類:java.lang.String 類。
存盤庫界面extends CrudRepository<MyEntity, PrimaryKey>。
我@IdClass(PrimaryKey.class)在我的@Entity課堂上使用,并用@Id. 中有一個欄位PrimaryKey,它是一個String. 我們這樣做是為了保持我們的代碼庫一致,以便每個@Entity總是將其主鍵宣告為復合鍵。
我自己的分析(可能有誤)
出于某種原因,JPA 在內部呼叫em.find(MyEntity.class, primaryKeyString)而不是PrimaryKey從該字串構建實體并使用它,因此出現錯誤。
當我嘗試呼叫時會發生同樣的錯誤repository.deleteById(correspondingPrimaryKeyInstance)。
框架代碼
這來自org.springframework.data.jpa.repository.support.SimpleJpaRepository,我在事情失敗的地方添加了一條評論:
@Override
@Transactional
@SuppressWarnings("unchecked")
public void delete(T entity) {
Assert.notNull(entity, "Entity must not be null!");
if (entityInformation.isNew(entity)) {
return;
}
Class<?> type = ProxyUtils.getUserClass(entity);
T existing = (T) em.find(type, entityInformation.getId(entity)); // IT FAILS HERE... `entityInformation.getId(entity)` returns a String instead of the expected `PrimaryKey`
// if the entity to be deleted doesn't exist, delete is a NOOP
if (existing == null) {
return;
}
em.remove(em.contains(entity) ? entity : em.merge(entity));
}
代碼
- 存盤庫:
public interface MyEntityCRUDRepository extends CrudRepository<MyEntity, PrimaryKey> { }
public interface MyEntityCustomRepository { /* some custom operations */ }
@Repository
public interface MyEntityRepository extends MyEntityCRUDRepository, MyEntityCustomRepository { }
- 服務:
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class MyEntityService {
private final MyEntityRepository repository;
public void destroy(final PrimaryKey pk) {
// repository.deleteById(pk); // also returns the error
MyEntity myEntity = repository.findById(pk)
.orElseThrow(() -> new IllegalArgumentException(DOES_NOT_EXIST));
repository.delete(myEntity); // returns the error
}
}
- JPA物體:
@Entity
@Table(name = "myentity")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@IdClass(PrimaryKey.class)
public class MyEntity {
@Id
@Column(name = "the_id", updatable = false)
private String theId;
// other fields which aren't part of the primary key
}
- 主鍵類:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PrimaryKey implements Serializable {
private String theId;
}
uj5u.com熱心網友回復:
臨時修復:@IdClass當您只有一個 ID 屬性時不要使用。
@Entity
@Table(name = "myentity")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
//@IdClass(PrimaryKey.class)
public class TemporaryReservation {
@Id
@Column(name = "the_id", updatable = false)
private String theId;
// other fields which aren't part of the primary key
}
public interface MyEntityCRUDRepository extends CrudRepository<MyEntity, String> { }
更改后,在其余代碼中進行適當調整。
uj5u.com熱心網友回復:
原來是Spring Data. 請參閱相關(現已解決)問題:https : //github.com/spring-projects/spring-data-jpa/issues/2330。
其中一位維護者說:
另一種解決方法是讓您的物體實作
Persistable.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/318574.html
