findById()是否真的从JPA存储库加载数据



我是Hibernate的初学者。我做了几个简单的教程,并试图编写一个简单的商店后端。一切都正常工作,但我在单元测试中看到了一些奇怪的事情。当我保存一个实体,然后使用findById((检索它时,我似乎只是得到了我调用save((的同一个对象,甚至没有从数据库中检索实际值:

package com.bo.learnjava.shop1.repository;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "PRODUCTS")
public class Product {
@Id
@GeneratedValue
@Column(name="ID")
long id;

@Column(name="NAME")
String name = "";
@Column(name="PRICE_CENTS")
int priceCents = 0;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPriceCents() {
return priceCents;
}
public void setPriceCents(int priceCents) {
this.priceCents = priceCents;
}
public long getId() {
return id;
}
}
package com.bo.learnjava.shop1.repository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductRepository extends PagingAndSortingRepository<Product,Long> {
}
package com.bo.learnjava.shop1.repository;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
@DataJpaTest
public class ProductRepositoryTest {
@Autowired
ProductRepository repo;
@Test
void testProductRepository() {
Product p=new Product();

p.setName("Milk");
p.setPriceCents(134);

repo.save(p);

// Modify the value to check that repo.findById() actually retrieves *saved* data
p.setPriceCents(9999);
Optional<Product> productFromRepo=repo.findById(p.getId());**
// I expect productFromRepo to contain the values I called save() with
// (price == 134). But productFromRepo.get() returns exactly the same Java object 
// as p (with price == 9999), so no actual data was retrieved from the database - why?
assertTrue(productFromRepo.isPresent());
System.out.println("productFromRepo.priceCents="+productFromRepo.get().getPriceCents()); // Outputs 9999!
assertEquals(134,productFromRepo.get().getPriceCents()); // THIS FAILS!!!
}
}

为什么Hibernate会有这样的行为,我如何测试我通过Hibernate写入数据库的东西实际上是从数据库中检索回来的?

添加关于一级缓存的注释。如果您正在扩展JpaRepository,您可以使用repo.saveAndFlush(p);repo.save(p); repo.flush();以便立即将数据保存在数据库中。

之后,repo.findById(p.getId());将返回更新后的数据。

最新更新