java当实体中存在关系时,我可以只使用实体的id而不是从DB中获取实体吗?
我在Hibernate中使用Spring数据JPA
假设我定义了以下实体:
@Entity
@Table(name = "foods")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "food_id")
private Long foodId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "food_type_id")
@NotNull
private FoodType foodType;
...
}
@Entity
@Table(name = "food_types")
public class FoodType {
public static final Integer PERISHABLE;
public static final Integer NON_PERISHABLE;
@Id
@Column(name = "food_type")
private Integer foodTypeId;
private String name;
...
}
每次我想要创建Food
实体并将其保存到数据库时,当前代码如下所示:
Food food = new Food();
FoodType foodType = foodTypeRepository.findById(FoodType.PERISHABLE); // Call to DB to get Entity
food.setFoodType(foodType);
....
foodRepository.save(food);
<如果我们考虑食物类型在dB中是恒定的。我可以这样使用它吗:
Food food = new Food();
FoodType foodType = new FoodType();
foodType.setFoodTypeId(FoodType.PERISHABLE); // No Call to DB
food.setFoodType(foodType);
....
foodRepository.save(food);
我已经对它进行了测试,是的,我可以这样使用它,hibernate将保存Food
实体,但是是否有任何缺点、陷阱等。。。我没有看见
这只是一个简单的例子来说明这个想法,它是旧遗留项目的一部分,我不能修改它来从数据库中删除常量,而是使用枚举
# 1 楼答案
您不需要获取与
FoodType.PERISHABLE
关联的实体来设置Food
实体与它的关系,我不知道直接使用FoodType.PERISHABLE
的任何副作用或陷阱,只要它是有效的FoodType
id正如其他人提到的,你也可以使用JpaRepository#getById(ID id),这可能是解决这个问题的更规范的方法:
# 2 楼答案
为了避免额外呼叫DB,您应该使用:
在引擎盖下,它调用
EntityManager.getReference
来获取对实体的引用,而不必加载其数据,而foodTypeRepository.findById
则导致调用EntityManager.find
来获取实体及其数据另请参见hibernate文档的this section
请注意,您不能使用:
如在本例中,Hibernate考虑^ {< CD4>}作为Time实体(不与A^ {A2}关联),并且如果在{{{CD5}}关联上有正确的cascading,则尝试将其保存为新记录。
另外,正如documentation中提到的,方法
JpaRepository#getOne(ID)
已被弃用,您应该使用JpaRepository#getById(ID)