在我的Web应用中,在服务布局中,我对“餐厅”实体使用代理(在“餐厅”字段上使用fetchtype.lazy)。
User user = userRepository.get(userId);
/*
Getting proxy here, not restaurant object
*/
Restaurant userRestaurantRef = user.getRestaurant();
if (userRestaurantRef != null){
restaurantRepository.decreaseRating(userRestaurantRef.getId());
}
restaurantRepository.increaseRating(restaurantId);
/*
"getReference" invokes "getOne()"
*/
user.setRestaurant(restaurantRepository.getReference(restaurantId));
userRepository.save(user);
mockMvc.perform(put(REST_URL + RESTAURANT1_ID)
.param("time", "10:30")
.with(userHttpBasic(USER)))
.andExpect(status().isNoContent());
Restaurant restaurant = restaurantRepository.get(RESTAURANT1_ID);
Restaurant restaurantBefore = restaurantRepository.get(RESTAURANT1_ID);
mockMvc.perform(put(REST_URL + RESTAURANT1_ID)
.param("time", "10:30")
.with(userHttpBasic(USER)))
.andExpect(status().isNoContent());
Restaurant restaurantAfter = restaurantRepository.get(RESTAURANT1_ID);
“get()”进入存储库:
@Override
public Restaurant get(int id) {
return repository.findById(id).orElse(null);
}
方法或服务类本身有@transaction
注释吗?
这可以解释观察到的行为。
当在事务中执行方法时,从数据库获取或合并/保存到数据库的实体将被缓存,直到事务结束(通常是方法结束)。这意味着对具有相同ID的实体的任何调用都将直接从缓存返回,而不会命中数据库。
回到您的示例:
findbyid(id)
,然后调用getone(id)
为两者返回相同的实体对象getone(id)
,然后调用findbyid(id)
为这两个调用返回相同的代理这是因为它们共享相同的ID
,并且在相同的事务中执行。
根据JPA持久化提供程序的实现方式,这很可能总是在第一次访问时返回一个实例并抛出一个EntityNotFoundException。其中一些会立即拒绝无效的标识符。
参数:id-不能为空。
返回:对具有给定标识符的实体的引用。
返回:具有给定id的实体,如果没有找到,则返回可选的#empty()
我花了一些时间寻找更好的解释,但没有找到,所以我不确定这是findbyid()
实现中的一个bug,还是一个没有(很好地)记录的特性。
作为解决这个问题的变通办法,我可以建议:
java prettyprint-override">import javax.persistence.EntityManager;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class SomeServiceImpl implements SomeService {
private final SomeRepository repository;
private final EntityManager entityManager;
// constructor, autowiring
@Override
public void someMethod(long id) {
SomeEntity getOne = repository.getOne(id); // Proxy -> added to cache
entityManager.detach(getOne); // removes getOne from the cache
SomeEntity findById = repository.findById(id).get(); // Entity from the DB
}
import javax.persistence.EntityManager;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class SomeServiceImpl implements SomeService {
private final SomeRepository repository;
private final EntityManager entityManager;
// constructor, autowiring
@Override
public void someMethod(long id) {
SomeEntity getOne = repository.getOne(id); // Proxy -> added to cache
entityManager.clear(); // clears the cache
SomeEntity findById = repository.findById(id).get(); // Entity from the DB
}
编辑:
下面是一个简单的项目,演示了问题或特性(取决于观点)。
> -返回类型是实体和 -返回类型为实体 过程1需要一个额外的步骤,使用optional.get()从optional中获取实体。有什么不同吗?你推荐哪一种?
} 我得到了下面的结果。但是在这个结果中,高亮显示的行具有相同的列名,但是别名不同。为什么hibernate会得到相同的Cloumn? 冬眠:删除表,如果存在hibernate_sequence hibernate:删除表(如果存在)UserDetails Hibernate:如果存在,则删除表车辆Hibernate:创建表hibernate_sequence(next_val bigint)En
问题内容: 我在某处读到,函数应始终仅返回一种类型,因此以下代码被视为错误代码: 我想更好的解决方案是 返回None然后创建一个新的空元组不是更便宜的内存明智的选择吗?或者即使在较大的项目中,这种时差也太小而无法引起注意? 问题答案: 为什么函数应该返回一致类型的值?满足以下两个规则。 规则1-函数具有“类型”-输入映射到输出。它必须返回一致的结果类型,否则它不是函数。一团糟。 从数学上讲,我们说
问题内容: 今天,我了解并决定将其使用和测试。我知道整数是不可变的,因此id应该是(?)相同。但是,当我在提示中进行测试时,我注意到了一些细微的差异,并想找出其背后的原因。 凉!到目前为止,所有签出。但是之后… 好的,所以测试一下,我注意到此行为一直持续到256年。id最多可以是8位数字,然后257将返回更大的id,可以是15位数字。因此类型必须是8个字节。 所以我发现它与8个字节长有关,但是任何
当我执行普通Select时,返回正确的结果,但当我执行Select for DB uptime时,它始终返回相同的第一个结果。我确实检查了Postgres日志,我看到select被执行了。
我有这些实体 标准化ChannelStock。Java语言 NormalizedChannelStockId。Java语言 Channel.java 我面临的问题是 如图所示,savedentialities中返回的实体将其通道内部对象设置为null,以及其created\u at和updated\u at 这是正常的行为吗?当我在存储库上运行时,实体中的被正确地延迟加载,因此我相信实体在代码中被