java—当实体中存在关系时,我可以只使用实体的id而不从db中获取实体吗?

quhf5bfb  于 2021-07-14  发布在  Java
关注(0)|答案(2)|浏览(396)

我在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);

如果我们认为foodtype在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 但是有什么缺点,陷阱等。。。我没看见。
这只是一个简单的例子来说明这个想法,它是旧的遗留项目的一部分,我不能修改它来从数据库中删除常量,而是使用枚举。

gt0wga4j

gt0wga4j1#

为避免额外调用db,应使用:

FoodType foodType = foodTypeRepository.getOne(FoodType.PERISHABLE);

在引擎盖下它叫 EntityManager.getReference 获取对实体的引用而不必加载其数据(相对于 foodTypeRepository.findById 那是电话的线索 EntityManager.find 获取实体及其数据的。
另请参阅hibernate文档的这一部分。
p、 您不能使用:

Food food = new Food();
FoodType foodType = new FoodType();
foodType.setFoodTypeId(FoodType.PERISHABLE);

在这种情况下,考虑休眠 foodType 作为一个临时实体(与持久性上下文无关),并且如果您的服务器上有一个适当的级联,则会尝试将其保存为一个新记录 @ManyToOne 联想。

g6ll5ycj

g6ll5ycj2#

您不需要获取与关联的实体 FoodType.PERISHABLE 为了在 Food 我不知道使用它会有什么副作用或陷阱 FoodType.PERISHABLE 只要是有效的 FoodType 身份证件。
正如其他人提到的,您还可以使用jparepository#getbyid(id id),这可能是解决此问题的更规范的方法:
getbyid(id id)返回对具有给定标识符的实体的引用。根据jpa持久性提供程序的实现方式,这很可能总是返回一个示例,并在第一次访问时抛出entitynotfoundexception。其中一些会立即拒绝无效的标识符。

相关问题