JpaObjectRetrievalFailureException在一個簡單的 Spring Boot 應用程式中,當我嘗試使用一對多關聯和客戶端分配的 id 保存物體時,我面臨著一個問題。
請查看這些物體和這個簡單的存盤庫:
@Entity
@Table(name = "cart")
public class Cart {
@Id
@Column(name = "id")
private UUID id;
@Column(name = "name")
private String name;
@OneToMany
@JoinColumn(name = "cart_id")
private List<Item> items;
// constructors, getters, setters, equals and hashCode ommitted
}
@Entity
@Table(name = "item")
public class Item {
@Id
@Column(name = "id")
private UUID id;
@Column(name = "name")
private String name;
// constructors, getters, setters, equals and hashCode ommitted
}
public interface CartRepository extends JpaRepository<Cart, UUID> {
}
我寫了這個測驗:
@DataJpaTest
class CartRepositoryTest {
@Autowired
private CartRepository cartRepository;
@Test
void should_save_cart() {
// GIVEN
final var cart = new Cart(UUID.randomUUID(), "cart");
final var item = new Item(UUID.randomUUID(), "item");
cart.setItems(List.of(item));
// WHEN
final var saved = cartRepository.save(cart);
// THEN
final var fetched = cartRepository.findById(saved.id());
assertThat(fetched).isPresent();
}
}
當我運行測驗時,呼叫cartRepository.save(cart)失敗并顯示:
Unable to find com.example.testjpaonetomany.domain.Item with id f5658508-f3d0-4d9b-a1f0-17b614753356; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.example.testjpaonetomany.domain.Item with id f5658508-f3d0-4d9b-a1f0-17b614753356
org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find com.example.testjpaonetomany.domain.Item with id f5658508-f3d0-4d9b-a1f0-17b614753356; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.example.testjpaonetomany.domain.Item with id f5658508-f3d0-4d9b-a1f0-17b614753356
at app//org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:379)
at app//org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:235)
at app//org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at app//org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at app//org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at app//org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at app//org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at app//org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at app//org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at app/jdk.proxy3/jdk.proxy3.$Proxy105.save(Unknown Source)
at app//com.example.testjpaonetomany.repository.CartRepositoryTest.should_save_cart(CartRepositoryTest.java:28)
如果我通過添加 for id 來修改我的物體@GeneratedValue,并且在我的測驗中,我替換UUID.randomUUID()為null將 ID 生成委托給 Hibernate,則測驗通過。
如何處理客戶端生成的 id?
uj5u.com熱心網友回復:
原因是您僅保存父物件(這絕對正確且很好)但仍需要解釋 JPA 應該傳播該操作,即
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "cart_id")
private List<Item> items;
作為小的改進,我建議將 UUID 生成放入建構式中并通過專用方法建立關系,即
final var cart = new Cart("cart");
cart.addItem(new Item("item"));
并且可能考慮使用em.persist()而不是repository.save()因為它select首先發出請求,以防@Augusto 提到的使用uuids
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/521158.html
標籤:爪哇弹簧靴休眠jpa
上一篇:無法加載配置類:net.guides.springboot2.crud.JPAspringboot中的應用程式錯誤
下一篇:如何從目標端加入單向物體?
